2010-12-04 34 views
22

我發現堆大小隨應用程序需要自動增加,直到手機的最大堆大小爲止。我也看到,最大堆大小根據設備而不同。有關最大堆大小和可用內存的兩個問題android

所以我的第一個問題是,什麼是Android設備上的典型的最大堆大小?我測試了一個手機的內存分配,這個手機能夠使用超過40MB的堆,而另一個手機則在20s內發出了OutOfMemory錯誤。常用設備中最低的是什麼?常用設備中的最高是多少?是否有標準或平均水平?

第二個問題,而且更重要的,是如何保證您能夠使用每個設備的可用資源,但切忌用太多了?我知道有諸如onLowMemory()這樣的方法,但這些方法似乎只適用於整個系統內存,而不僅僅是針對特定應用程序的堆。

有沒有一種方法來檢測該設備的最大堆大小,也當可用堆內存達到最低點爲您的應用程序檢測?

例如,如果該裝置只允許24MB的最大堆和該應用已接近該極限中分配,那麼它可以檢測和縮減。但是,如果設備可以舒適地處理更多,它將能夠利用可用的功能。

由於

+3

它涉及處理圖像,內存20MB很容易用圖像來使用。一次使用更少的內存和更少的進程是完全正確的,但如果設備能夠處理它,我希望能夠讓應用程序更快地處理它們。 – cottonBallPaws 2010-12-04 05:16:49

回答

8

早期器件具有每個應用帽16MB的。後來的設備增加到24MB。未來的設備可能會有更多的可用。

該值反映了設備上可用的物理內存和顯示設備的屬性(因爲能夠顯示更多顏色的大屏幕通常需要更大的位圖)。

編輯:附加沉思...

我看了一篇文章,不是太不久前指出,垃圾收集分配器基本上與無限懷念造型的機器。您可以儘可能多地分配,並且會處理細節。 Android主要以這種方式工作;你堅持引用你所需要的東西,對你不可能引用的東西進行軟/弱引用,並放棄對你再也不需要的東西的引用。 GC把它全部整理出來。

在你的具體情況下,你會使用軟引用來保持你不需要需要在內存中的東西,但如果有足夠的空間要保留。

這開始與位圖分離,主要是因爲一些早期的設計決策導致了「外部分配」機制。此外,軟參考機制需要一些調整 - 初始版本傾向於保留所有內容或丟棄所有內容。

Dalvik堆正處於積極的發展階段(請參閱例如關於Android 2.3「Gingerbread」的介紹併發GC的注意事項),所以希望這些問題將在未來版本中得到解決。

編輯:更新...

「外部分配」 機制走在4.0(冰淇淋三明治)。 Bitmaps的像素數據現在存儲在Dalvik堆上,避免了以前的煩惱。

最近的設備(例如Nexus 4)將堆大小限制在96MB或更大。

應用程序的內存限制的一般意義可以從ActivityManager.getMemoryClass()的「內存類」獲得。可以從java.lang.Runtime功能maxMemory()獲得更具體的值。

5

這裏是 「正常的」(見下文)堆對於一些特定的設備的尺寸:

  • G1:16MB
  • 摩托德羅伊德:24MB
  • Nexus之一:32MB
  • 優派GTab: 32MB
  • NOVO7騎士:60MB

我說 「正常」,因爲一些Android版本(例如CyanogenMod)將允許用戶手動調整堆棧限制。結果可能大於或小於「正常」值。

請參閱此答案以獲取其他信息,包括如何找出程序化實際堆大小,以及如何區分絕對堆大小限制和應理想尊重的堆限制其他:

Detect application heap size in Android

檢測到您當前的內存使用率是什麼,你可以嘗試使用Runtime類的totalMemory()方法。然而,我讀過報道說Android操作系統的不同版本/實現可能有不同的策略,關於本地內存(從中分配用於位圖的後備內存)是否針對堆的最大值進行計數。而且,從版本3.0起,本機內存直接從應用程序自己的堆中獲取。

這個計算的有效性讓我認爲在運行時監視應用程序對內存的使用是一個錯誤,不斷地將其與可用的數量進行比較。另外,如果你是在所涉及的計算的中間,發現你正在運行內存,它並不總是方便或合理可取消計算,如果你這樣做可能會給用戶帶來不良體驗。相反,您可以嘗試根據應用程序的功能行爲預先定義某些模式或約束,以確保它在任何當前設備的相關堆限制(如在您的應用程序初始化過程中檢測到)時進入。例如,如果您有一個應用程序使用大量必須一次加載到內存中的單詞,那麼您可能會限制您的應用程序,以便對於較小的堆限制只包含較常見單詞的較小列表可以加載,而對於較大的堆限制,可以加載包含更多單詞的完整列表。

也有Java編程技術,讓您聲明某些記憶是通過對需求的垃圾收集可回收的,即使它已經存在的「軟」(而不是硬)引用。如果你有,你想保留在內存中,但可以從非易失性存儲,如果需要重新加載的數據(即高速緩存),那麼你可以考慮使用軟引用有這樣的內存自動釋放時,你的應用程序開始撞擊你的堆的上限。見Android的這個網頁,軟引用信息:

http://developer.android.com/reference/java/lang/ref/SoftReference.html