當前位置:首頁 » 安卓系統 » 安卓中什麼時候會觸發gc

安卓中什麼時候會觸發gc

發布時間: 2022-09-05 09:16:28

A. 一次完整的gc流程是什麼

JVM堆分為新生代和老年代,大概比例的1:2,其中新生代又分為1個eden區和2個survivor區,大概比例是8:1:1

GC過程:

1、大對象直接進入到老年代。

2、小對象先在eden區分配內存,當eden滿了後,觸發一次Minor GC,清理eden區域。

3、存活下來的對象進入到survivor區域,年齡+1。

4、當年齡>15(默認)時進入到老年代,當老年代滿了後觸發一次Full GC。

在正式 Minor GC 前,JVM 會先檢查新生代中對象,是比老年代中剩餘空間大還是小。為什麼要做這樣的檢查呢?原因很簡單,假如 Minor GC 之後 Survivor 區放不下剩餘對象,這些對象就要進入到老年代,所以要提前檢查老年代是不是夠用。這樣就有兩種情況:

老年代剩餘空間大於新生代中的對象大小,那就直接 Minor GC,GC 完 survivor 不夠放,老年代也絕對夠放。

老年代剩餘空間小於新生代中的對象大小,這個時候就要查看是否啟用了「老年代空間分配擔保規則」,具體來說就是看-XX:-HandlePromotionFailure參數是否設置了(一般都會設置)。

老年代空間分配擔保規則是這樣的。如果老年代中剩餘空間大小,大於歷次 Minor GC 之後剩餘對象的大小,那就允許進行 Minor GC。因為從概率上來說,以前的放的下,這次的也應該放的下。那就有兩種情況:

老年代中剩餘空間大小,大於歷次 Minor GC 之後剩餘對象的大小,進行 Minor GC。

老年代中剩餘空間大小,小於歷次 Minor GC 之後剩餘對象的大小,進行 Full GC,把老年代空出來再檢查。

B. 什麼情況下會觸發minor gc和full gc

當 JVM 無法為一個新的對象分配空間時會觸發 Minor GC,比如當 Eden 區滿了。所以分配率越高,越頻繁執行 Minor GC。
內存池被填滿的時候,其中的內容全部會被復制,指針會從0開始跟蹤空閑內存。Eden 和 Survivor 區進行了標記和復制操作,取代了經典的標記、掃描、壓縮、清理操作。所以 Eden 和 Survivor 區不存在內存碎片。寫指針總是停留在所使用內存池的頂部。
執行 Minor GC 操作時,不會影響到永久代。從永久代到年輕代的引用被當成 GC roots,從年輕代到永久代的引用在標記階段被直接忽略掉。
質疑常規的認知,所有的 Minor GC 都會觸發「全世界的暫停(stop-the-world)」,停止應用程序的線程。對於大部分應用程序,停頓導致的延遲都是可以忽略不計的。其中的真相就 是,大部分 Eden 區中的對象都能被認為是垃圾,永遠也不會被復制到 Survivor 區或者老年代空間。如果正好相反,Eden 區大部分新生對象不符合 GC 條件,Minor GC 執行時暫停的時間將會長很多。

C. 為什麼安卓系統用久了會卡,蘋果系統卻依然流暢誰能科普下,比較容易懂

蘋果系統的設計和體驗口碑一直特別好。比如打開控制中心、多任務處理切換,或APP中滾動瀏覽等都會比安卓更流暢、更靈敏。盡管安卓的動畫效果、全面屏手勢等已經可以和蘋果系統硬扛,但整體視覺效果不如蘋果系統。


以上個人淺見,歡迎批評指正。認同我的看法,請點個贊再走,感謝!喜歡我的,請關注我,再次感謝!


D. android 如何停用gc

1、設置環境變數GOGC=off。
2、運行時調用debug.SetGCPercent(-1)。GC理解為android中的垃圾回收,常見觸發垃圾回收是計數引用,當引用計數為0時會觸發垃圾回收。此時系統並不會回收內存,而是會當作垃圾存放起來,當下次需要的時候,快速使用。關閉GC系統就會徹底回收內存。

E. Android UI卡頓原因及解決辦法

渲染機制介紹

為了分析UI卡頓,我們有必要理解一下渲染機制,這套渲染機制適用於絕大部分的屏幕渲染,其中包括Android手機等眾多屏幕設備。

渲染的一些重要參數:

屏幕刷新理想的頻率(硬體的角度):60Hz

理想的一秒內繪制的幀數,幀率(屏幕刷新的角度):60fps

這兩個參數都是理想值,指代的都是同一個概念。實際情況中難免會比它們低。在60fps內,系統會得到發送的VSYNC(垂直刷新/繪制)信號去進行渲染,就會正常地繪制出我們需要的圖形界面。Android手機進行繪制的時候,GPU幫助我們將UI組件等計算成紋理Texture和三維圖形Polygons,同時會使用OpenGL---會將紋理和Polygons緩存在GPU內存裡面。

其中,VSYNC:有兩個概念

Refresh Rate:屏幕在一秒時間內刷新屏幕的次數----有硬體的參數決定,比如60HZ,即屏幕每秒刷新60次

Frame Rate:GPU在一秒內繪制操作的幀數,比如:60fps,

基本結論

要達到60fps,就要求:每一幀只能停留16ms。(大概就是1000ms/60 ~= 16ms刷新一次)

內存抖動是因為大量的對象被創建又在短時間內馬上被釋放。

 瞬間產生大量的對象會嚴重佔用Young Generation的內存區域,當達到閥值,剩餘空間不夠的時候,也會觸發GC。即使每次分配的對象佔用了很少的內存,但是他們疊加在一起會增加Heap的壓力,從而觸發更多其他類型的GC。這個操作有可能會影響到幀率,並使得用戶感知到性能問題。

Android裡面是一個三級Generation的內存模型,最近分配的對象會存放在Young Generation區域,當這個對象在這個區域停留的時間達到一定程度,它會被移動到Old Generation,最後到Permanent Generation區域。

Android每個16ms就會繪制一次Activity,通過上述的結論我們知道,如果由於一些原因導致了我們的邏輯、CPU耗時、GPU耗時大於16ms( 應用卡頓的根源就在於16ms內不能完成繪制渲染合成過程,16ms需要完成視圖樹的所有測量、布局、繪制渲染及合成 ),UI就無法完成一次繪制,那麼就會造成卡頓。

比如說,在16ms內,發生了頻繁的GC:

在第一個16ms內,UI正常地完成了繪制,那麼屏幕不會卡頓。

在第二個16ms內,由於某些原因觸發了頻發的GC,UI無法在16ms內完成繪制,就會卡頓。

UI卡頓外部和內部常見原因

下面總結一些常見的UI卡頓原因:

  1.內存抖動的問題

 2.方法太耗時了(CPU佔用)

    1) CPU計算時間,CPU的測量、布局時間

     2)CPU將計算好的Polygons和Texture傳遞到GPU的時候也需要時間。OpenGL ES API允許數據上傳到GPU後可以對數據進行保存,緩存到display list。因此,我們平移等操作一個view是幾乎不怎麼耗時的 。

    3) GPU進行格柵化

當我們的布局是用的FrameLayout的時候,我們可以把它改成merge,可以避免自己的幀布局和系統的ContentFrameLayout幀布局重疊造成重復計算(measure和layout)。

使用ViewStub:當載入的時候才會佔用。不載入的時候就是隱藏的,僅僅佔用位置。

CPU優化建議

針對CPU的優化,從減輕加工View對象成Polygons和Texture來下手:

View Hierarchy中包涵了太多的沒有用的view,這些view根本就不會顯示在屏幕上面,一旦觸發測量和布局操作,就會拖累應用的性能表現。那麼我們就需要利用工具進行分析。

如何找出裡面沒用的view呢?或者減少不必要的view嵌套。

我們利用工具:Hierarchy Viewer進行檢測,優化思想是:查看自己的布局,層次是否很深以及渲染比較耗時,然後想辦法能否減少層級以及優化每一個View的渲染時間。

我們打開APP,然後打開Android Device Monitor,然後切換到Hierarchy Viewer面板。除了看層次結構之外,還可以看到一些耗時的信息:

三個圓點分別代表:測量、布局、繪制三個階段的性能表現。

1)綠色:渲染的管道階段,這個視圖的渲染速度快於至少一半的其他的視圖。

2)黃色:渲染速度比較慢的50%。

3)紅色:渲染速度非常慢。

GPU優化建議就是一句話:盡量避免過度繪制(overdraw)

一、背景經常容易造成過度繪制。

手機開發者選項裡面找到工具:Debug GPU overdraw,其中,不同顏色代表了繪制了幾次:

F. jvm什麼時候會觸發full gc

full gc是發生在老年代的gc,所有的gc觸發都是因為jvm覺得內存緊張了,所以老年代的full gc也不例外。具體的原因有很多,比如空間分配擔保中,發生minor gc(新生代中)jvm會檢測之前每次晉升到老年代的平均大小是否大於老年代的剩餘空間,如果大於則直接進行full gc,不管怎樣,觸發gc都有一個宗旨:內存緊張了。建議看看深入java虛擬機。

G. Android 接收大量數據如何避免頻繁GC

GC會stop the world。會暫停程序的執行,帶來延遲的代價。所以在開發中,我們不希望GC的次數過多。
本文將討論如何在開發中改善各種細節,從而減少GC的次數。
(1)對象不用時最好顯式置為 Null
一般而言,為 Null 的對象都會被作為垃圾處理,所以將不用的對象顯式地設
為 Null,有利於 GC 收集器判定垃圾,從而提高了 GC 的效率。
(2)盡量少用 System.gc()
此函數建議 JVM進行主 GC,雖然只是建議而非一定,但很多情況下它會觸發
主 GC,從而增加主 GC 的頻率,也即增加了間歇性停頓的次數。
(3)盡量少用靜態變數
靜態變數屬於全局變數,不會被 GC 回收,它們會一直佔用內存。
(4)盡量使用 StringBuffer,而不用 String 來累加字元串
由於 String 是固定長的字元串對象,累加 String 對象時,並非在一個 String對象中擴增,而是重新創建新的 String 對象,如 Str5=Str1+Str2+Str3+Str4,這條語句執行過程中會產生多個垃圾對象,因為對次作「+」操作時都必須創建新的 String 對象,但這些過渡對象對系統來說是沒有實際意義的,只會增加更多的垃圾。 避免這種情況可以改用 StringBuffer 來累加字元串,因 StringBuffer是可變長的,它在原有基礎上進行擴增,不會產生中間對象
(5)分散對象創建或刪除的時間
集中在短時間內大量創建新對象,特別是大對象,會導致突然需要大量內存,JVM 在面臨這種情況時,只能進行主 GC,以回收內存或整合內存碎片,從而增加主 GC 的頻率。
集中刪除對象,道理也是一樣的。 它使得突然出現了大量的垃圾對象,空閑空間必然減少,從而大大增加了下一次創建新對象時強制主 GC 的機會。
(6) 盡量少用 finalize 函數
因為它會加大 GC 的工作量, 因此盡量少用finalize 方式回收資源。
(7) 使用軟引用類型
如果需要使用經常用到的圖片, 可以使用軟引用類型, 它可以盡可能將圖片保存在內存中, 供程序調用, 而不引起 OutOfMemory。

H. jvm什麼時候會觸發full gc

除直接調用System.gc外,觸發Full GC執行的情況有如下四種。
1. 舊生代空間不足
舊生代空間只有在新生代對象轉入及創建為大對象、大數組時才會出現不足的現象,當執行Full GC後空間仍然不足,則拋出如下錯誤:
java.lang.OutOfMemoryError: Java heap space
為避免以上兩種狀況引起的FullGC,調優時應盡量做到讓對象在Minor GC階段被回收、讓對象在新生代多存活一段時間及不要創建過大的對象及數組。
2. Permanet Generation空間滿
PermanetGeneration中存放的為一些class的信息等,當系統中要載入的類、反射的類和調用的方法較多時,Permanet Generation可能會被占滿,在未配置為採用CMS GC的情況下會執行Full GC。如果經過Full GC仍然回收不了,那麼JVM會拋出如下錯誤信息:
java.lang.OutOfMemoryError: PermGen space
為避免Perm Gen占滿造成Full GC現象,可採用的方法為增大Perm Gen空間或轉為使用CMS GC。
3. CMS GC時出現promotion failed和concurrent mode failure
對於採用CMS進行舊生代GC的程序而言,尤其要注意GC日誌中是否有promotion failed和concurrent mode failure兩種狀況,當這兩種狀況出現時可能會觸發Full GC。
promotionfailed是在進行Minor GC時,survivor space放不下、對象只能放入舊生代,而此時舊生代也放不下造成的;concurrent mode failure是在執行CMS GC的過程中同時有對象要放入舊生代,而此時舊生代空間不足造成的。
應對措施為:增大survivorspace、舊生代空間或調低觸發並發GC的比率,但在JDK 5.0+、6.0+的版本中有可能會由於JDK的bug29導致CMS在remark完畢後很久才觸發sweeping動作。對於這種狀況,可通過設置-XX:CMSMaxAbortablePrecleanTime=5(單位為ms)來避免。
4. 統計得到的Minor GC晉升到舊生代的平均大小大於舊生代的剩餘空間
這是一個較為復雜的觸發情況,Hotspot為了避免由於新生代對象晉升到舊生代導致舊生代空間不足的現象,在進行Minor GC時,做了一個判斷,如果之前統計所得到的Minor GC晉升到舊生代的平均大小大於舊生代的剩餘空間,那麼就直接觸發Full GC。
例如程序第一次觸發MinorGC後,有6MB的對象晉升到舊生代,那麼當下一次Minor GC發生時,首先檢查舊生代的剩餘空間是否大於6MB,如果小於6MB,則執行Full GC。
當新生代採用PSGC時,方式稍有不同,PS GC是在Minor GC後也會檢查,例如上面的例子中第一次Minor GC後,PS GC會檢查此時舊生代的剩餘空間是否大於6MB,如小於,則觸發對舊生代的回收。
除了以上4種狀況外,對於使用RMI來進行RPC或管理的Sun JDK應用而言,默認情況下會一小時執行一次Full GC。可通過在啟動時通過- java-Dsun.rmi.dgc.client.gcInterval=3600000來設置Full GC執行的間隔時間或通過-XX:+ DisableExplicitGC來禁止RMI調用System.gc。

I. majorgc觸發條件

Major GC通常是跟full GC是等價的,收集整個GC堆。但因為HotSpot VM發展了這么多年,外界對各種名詞的解讀已經完全混亂了,當有人說「major GC」的時候一定要問清楚他想要指的是上面的full GC還是old gen。

最簡單的分代式GC策略,按HotSpot VM的serial GC的實現來看,觸發條件是:
young GC:當young gen中的eden區分配滿的時候觸發。注意young GC中有部分存活對象會晉升到old gen,所以young GC後old gen的佔用量通常會有所升高。
full GC:當准備要觸發一次young GC時,如果發現統計數據說之前young GC的平均晉升大小比目前old gen剩餘的空間大,則不會觸發young GC而是轉為觸發full GC(因為HotSpot VM的GC里,除了CMS的concurrent collection之外,其它能收集old gen的GC都會同時收集整個GC堆,包括young gen,所以不需要事先觸發一次單獨的young GC);或者,如果有perm gen的話,要在perm gen分配空間但已經沒有足夠空間時,也要觸發一次full GC;或者System.gc()、heap mp帶GC,默認也是觸發full GC。
HotSpot VM里其它非並發GC的觸發條件復雜一些,不過大致的原理與上面說的其實一樣。
當然也總有例外。Parallel Scavenge(-XX:+UseParallelGC)框架下,默認是在要觸發full GC前先執行一次young GC,並且兩次GC之間能讓應用程序稍微運行一小下,以期降低full GC的暫停時間(因為young GC會盡量清理了young gen的死對象,減少了full GC的工作量)。這是HotSpot VM里的奇葩嗯。

並發GC的觸發條件就不太一樣。以CMS GC為例,它主要是定時去檢查old gen的使用量,當使用量超過了觸發比例就會啟動一次CMS GC,對old gen做並發收集。

J. android中的GC是什麼意思

你指的是這個嗎Gabage Collection?垃圾回收,是.net中對內存管理的一種功能。垃圾回收器跟蹤並回收託管內存中分配的對象,定期執行垃圾回收以回收分配給沒有有效引用的對象的內存。當使用可用內存不能滿足內存請求時,GC會自動進行。 在進行垃圾回收時,垃圾回收器回首先搜索內存中的託管對象,然後從託管代碼中搜索被引用的對象並標記為有效,接著釋放沒有被標記為有效的對象並收回內存,最後整理內存將有效對象挪動到一起。

熱點內容
php表單注冊 發布:2025-01-11 18:43:02 瀏覽:160
虛擬存儲功能 發布:2025-01-11 18:43:01 瀏覽:887
ninjaandroid 發布:2025-01-11 18:26:10 瀏覽:526
華為的編譯器可以用幾個軟體 發布:2025-01-11 18:18:18 瀏覽:620
python中的turtle 發布:2025-01-11 18:06:08 瀏覽:399
羅布樂思賬號密碼手機號多少 發布:2025-01-11 18:00:55 瀏覽:403
在廣州什麼配置的車才能跑滴滴 發布:2025-01-11 18:00:52 瀏覽:893
安卓手機哪個生態好 發布:2025-01-11 17:56:01 瀏覽:274
資料庫數據的一致性 發布:2025-01-11 17:30:45 瀏覽:710
手機怎麼設置手勢安卓 發布:2025-01-11 17:15:54 瀏覽:965