簡體   English   中英

小型對象的池是否比Android的Java垃圾收集器更高效?

[英]Is Pooling for Small Objects More Efficient than Android's Java Garbage Collector?

所以,我正在讀這篇文章: http//www.ibm.com/developerworks/java/library/j-jtp09275/index.html ,其中說:“公共服務公告:對象池現在是一個嚴重的性能損失,除了最重量級的對象,即使這樣,在不引入並發性瓶頸的情況下做到正確也很棘手,“並將其視為面值。 本文討論了分代GC,解除分配,線程局部分配和轉義分析。

但是,我腦子里只有一個小小的聲音問我,“但這對Android中的垃圾收集器實現是否正確?” 而且我不知道答案。 我甚至不知道如何找到答案。

我記得當我為經常使用的小對象實現池化時,在我的Android應用程序中運行GC的頻率較低。 不確定這是否意味着更快的應用程序..此外,GC運行更頻繁而沒有池(根據logcat),所以我認為Android的GC實現失去了匯集..但這個假設幾乎沒有支持,因為我沒有注意到任何顯着的性能差異,無論是否合並。

所以..這里的任何人都知道,對於經常使用的小物件,池的效率是否比Android的GC更高效?

這里的任何人都知道,對於經常使用的小對象,池化是否比Android的GC更高效?

這取決於你如何測量“有效”,“小”和“經常”。

對象池在Android本身的幾個地方使用,例如:

  • AdapterViewListView和kin)的整個Adapter框架是圍繞對象池設計的,這次是針對相對AdapterView對象(例如, ListView行可以很容易地為幾十KB)

  • SensorEvent對象被回收,這次對於每秒可能使用數十次的輕量級對象

  • 作為View通脹的一部分, AttributeSet對象被回收

等等。

其中一些是基於早期版本的Android中Dalvik的早期版本,當時我們的目標是使用純粹的解釋語言和相當天真的GC引擎,在100MHz以下的CPU。

但是,即使在今天,對象池還有一個超越即時性能的巨大優勢:堆碎片。

Java的GC引擎是一個壓縮垃圾收集器,意味着連續的空閑堆空間塊被組合成更大的塊。 Dalvik的GC引擎是一個非壓縮垃圾收集器,這意味着您分配的塊永遠不會成為更大塊的一部分。 這是許多開發人員搞砸位圖管理的地方 - 他們得到的OutOfMemoryError不是因為堆空間不足,而是因為堆碎片導致堆沒有足夠大的塊來進行所需的分配。

對象池避免了堆碎片,只是通過防止池化對象再次收集垃圾而不經常為池分配新對象(僅當池需要因同時使用太多而增長時)。

游戲開發者長期以來一直在Android中使用對象池,這源於Android的垃圾收集非並發時的回歸,當GC進行時“停止世界”。 現在,大多數Android設備都使用並發垃圾收集器,這可以減輕一些人的痛苦。

因此,對象池肯定仍然是一種相關技術。 但是,大多數情況下,我認為它可以用作對檢測到的問題的反應(例如,Traceview在GC中顯示太多時間,Traceview在對象構造函數中顯示太多時間,MAT顯示您有足夠的堆但是你得到OutOfMemoryErrors )。 例外是游戲開發 - 游戲開發者可能有自己的啟發式,因為現代Android設備仍然需要池化。

你的推理有一個謬誤。 更頻繁地運行GC並不表示某種性能下降。 那些更頻繁的GC運行也可能比那些不得不混淆對象池的頻率更快,壽命更短。

也就是說,我做了一些研究,這里有一些想法...幾年前,我的手機只有一個核心。 運行GC意味着從活動切換到GC線程。 即使使用並發GC和多核(現代設備有2-5個afaik),也可能會有輕微的暫停。

對於下一個交互序列,預先分配用戶可能需要的所有內容被建議作為游戲的好主意。 基本上遵循實時應用程序的咒語,與在應用程序的用戶體驗部分中具有一致的可測量性能相比,對整體性能的擔憂較少。

http://developer.android.com/training/articles/perf-tips.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM