2015-02-09 49 views
1

我正在爲實時目的開發應用程序。爲了解決一個非線性優化問題,我整合了Java求解器jcobyla(https://github.com/cureos/jcobyla)。求解器運行時,都會將垃圾收集器做了很多工作,有顯著運行時間:爲什麼垃圾收集器運行時沒有達到最大堆限制?

02-09 12:58:16.822: V/onCreate(7061): maxMemory:512524288k 

02-09 13:04:23.127: D/dalvikvm(7061): GC_FOR_ALLOC freed 10314K, 40% free 17304K/28544K, paused 16ms, total 16ms 

02-09 13:04:23.177: D/dalvikvm(7061): GC_FOR_ALLOC freed 3437K, 34% free 17304K/26196K, paused 11ms, total 11ms 

02-09 13:04:23.222: D/dalvikvm(7061): GC_FOR_ALLOC freed 3437K, 34% free 17304K/26196K, paused 10ms, total 10ms 

02-09 13:04:23.322: D/dalvikvm(7061): GC_FOR_ALLOC freed 10304K, 33% free 17303K/25452K, paused 18ms, total 18ms 

>02-09 13:04:23.367: D/dalvikvm(7061): GC_FOR_ALLOC freed 3437K, 33% free 17303K/25452K, paused 11ms, total 11ms 

02-09 13:04:23.417: D/dalvikvm(7061): GC_FOR_ALLOC freed 3437K, 33% free 17303K/25452K, paused 12ms, total 12ms 

02-09 13:04:23.522: D/dalvikvm(7061): GC_FOR_ALLOC freed 10304K, 40% free 17304K/28540K, paused 16ms, total 17ms 

02-09 13:04:23.567: D/dalvikvm(7061): GC_FOR_ALLOC freed 3437K, 34% free 17304K/26196K, paused 11ms, total 11ms 

02-09 13:04:23.612: D/dalvikvm(7061): GC_FOR_ALLOC freed 3437K, 34% free 17304K/26196K, paused 11ms, total 11ms 

我tryed很多事情,以防止GC運行。相信解算器達到應用程序的最大堆限制,我使用android:largeHeap="true"。在單獨的過程中運行解算器也沒有解決它。

正如你在上面的LogTag中看到的那樣,應用程序的最大堆限制約爲512MB,這足以滿足jcobyla(需要大約300MB)的限制。 GC在運行後告訴我,有24%的內存是24.85 MB。運行jcobyla時,應用的總RAM使用量約爲20 MB。

爲什麼限制GC顯示不同於應用程序的最大堆限制?

如何增加解算器可能的內存使用量?

如何防止GC運行?

回答

2

求解器運行垃圾回收器是做了很多工作,有顯著運行

GC_FOR_ALLOC意味着您的請求分配內存不能沒有圓GC的,可能的話應驗每次,擴大堆。

至極是綽綽有餘jcobyla(大約需要300MB)

我不知道你是如何確定,特別是爲Android。而且,你自己的分析認爲情況並非如此,否則你的堆將會增長到至少300MB,而且它還沒有這樣做。

爲什麼限制GC顯示與應用程序的最大堆限制不同?

因爲堆沒有發展到極限。目標是最大限度地減少進程的系統RAM佔用空間。進程越大,Android越需要終止其他進程以使所有內容適合系統RAM。這會損害用戶體驗,例如多任務處理。

如何增加求解器可能的內存使用量?

根據您的分析,您不需要增加解算器可能的內存使用量。

如何防止GC運行?

停止使用使用GC的編程語言,或停止對Android進行編程並切換到某些桌面操作系統。

您的應用程序是Android中的衆多應用程序之一,它是任何Android設備上的衆多應用程序之一。Android設備的系統內存很小 - 例如,Android One設備可能只有512MB的RAM。這是針對操作系統和所有正在運行的應用程序進程,而不僅僅是針對你。 Android,特別是Dalvik/ART,圍繞合作模式進行架構,每個流程都試圖最大限度地減少內存消耗。

但是:

  • ,如果你寫在C/C++使用NDK您的應用程序

    ,不僅是有沒有GC,但你有沒有堆的限制,比用戶認爲的淨效應等你應用程序由於其使用的系統RAM的數量而對其設備造成損害

  • 如果您爲其他OS編寫應用程序,那麼您將受制於該操作系統的內存管理策略,並且桌面操作系統更可能允許您更積極地使用系統RAM

+1

@canScan此外,Dalvik不使用移動垃圾收集器,因此即使您有足夠的可用空間來分配對象,也可能沒有足夠的連續可用空間,需要GC_FOR_ALLOC。 – 2015-02-09 14:47:23

+0

感謝您的詳細解答。 @CommonsWare的內存使用量是在桌面電腦上運行jcobyla測得的。看來NDK是達到我需要的性能的唯一途徑。 – canScan 2015-02-09 15:27:10

+0

@canScan:「在臺式計算機上運行jcobyla測量內存使用情況」 - 請注意,由於運行時間不同,內存使用情況將不同。 Tanis.7x指出,[Dalvik沒有壓縮(或移動)垃圾回收器](http://commonsware.com/blog/2014/06/16/art-garbage-collection.html),所以你可以讓你的堆變得更容易。一個普通的Java庫通常不會根據Android應用程序的需要(例如,回收現有對象而不是依靠GC和新分配)來最大限度地減少內存消耗。 – CommonsWare 2015-02-09 15:29:37