2016-03-19 6 views
1

Ich würde gerne wissen, ob dies möglich ist. Mein Ziel ist es, die Anzahl der GC-Operationen während einer langen Verarbeitung zu verringern.Erhöhen Sie die anfängliche Menge des freien Speichers in einer Android-Anwendung


In einer Android-Anwendung überprüfe ich die freie und max Heap-Größe mit:

Runtime runtime = Runtime.getRuntime(); 
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); 

System.out.println("freeMemory: " + runtime.freeMemory()); 
System.out.println("maxMemory: " + runtime.maxMemory()); 
System.out.println("memoryClass: " + am.getMemoryClass()); 

In LogCat für die onCreate() Methode heißt es:

freeMemory: 5678992 
maxMemory: 50331648 
memoryClass: 48 

Dann führe ich einige lange String Operationen und in der Mitte der Verarbeitung Ich überprüfe den Speicher erneut:

freeMemory: 1833176 

(Ich poste nicht den Code dieser Verarbeitung, weil für die tatsächliche Stufe ich die Java Codeoptimierung nicht ausführe, nur mit dem Gedächtnis arbeitend).

Und der GC wird ausgeführt, um den Speicher freizugeben. Dies verlangsamt die Anwendung:

GC_CONCURRENT freed 4760K, 42% free 7653K/13123K, paused 12ms+13ms, total 43ms 
GC_CONCURRENT freed 2012K, 42% free 7688K/13123K, paused 12ms+2ms, total 31ms 
GC_CONCURRENT freed 1839K, 42% free 7662K/13123K, paused 12ms+12ms, total 40ms 

Am Ende der Verarbeitung der freie Speicher ist:

freeMemory: 4605040 

Als Dokumentation sagt:

  • Runtime.freeMemory()

    Gibt die Anzahl der derzeit auf dem Heap verfügbaren Bytes zurück, ohne den Heapspeicher zu erweitern.

  • Runtime.maxMemory()

    Gibt die maximale Anzahl von Bytes der Heap zu erweitern.

Als ich die Runtime.maxMemory() zeigt den Speicher zu verstehen, die überschwemmt werden, sollte nicht die OutOfMemoryError zu verhindern. Und das Überschreiten des Runtime.freeMemory() Betrags führt nur dazu, dass der freie Speicher expandiert.

Also die GC freigebenden Operationen in meinem Code wurden durch die geringe Menge an freiem Speicher nach speicherintensiven Aktionen verursacht (wenn es hieß: freeMemory: 1 833 176). Aber die Gesamtmenge des freien Speichers wurde nicht erweitert, sondern nur freigegeben, um innerhalb der gleichen Startgrenze zu bleiben.

Und ich nehme an, die Anfangsmenge des freien Speichers war auch nicht sehr hoch (weil in der onCreate() Methode zeigte es). Und wenn ich anfangs ca. 10 MB frei hätte, würde der GC nicht passieren und somit würde die Anwendung die Verarbeitung schneller durchführen.


Die Frage ist also: Gibt es eine Weise, die ich die anfängliche Menge des freien Speichers erhöhen erweitern häufige GC Anrufe und Speicher zu verhindern?

Danke.

+0

Vom Standpunkt Ihrer Benutzer, wäre es besser, GC zu reduzieren, indem sie nicht ganz so viel Müll in erster Linie zu erzeugen (zB vermeidet zusätzliche Konstruktoraufrufe, vergeudet nicht System RAM). Da Sie den Code für die "lange Verarbeitung" nicht gepostet haben, ist es schwierig, Ihnen dabei behilflich zu sein. – CommonsWare

+0

Ich verstehe, dass ich den Code optimieren muss. Aber es ist eine separate Frage zur 'String'-Verarbeitung ... Hier würde ich gerne wissen, ob (in diesem Fall) um GC-Aufrufe zu reduzieren, ich nur mit den anfänglichen' 5MB' Speicher arbeiten kann (Begrenzung der Anzahl der erstellten Objekte) oder ich könnte es auf '10MB' erweitern. – mortalis

+0

Sie verstehen den GC ist nicht sehr korrekt. Es gibt viele Aufrufe an den ** Garbage Collector **, da Ihr Vorgang viel Müll erzeugt. Es spielt keine Rolle, wie viel Speicher zur Verfügung steht. Um den GC zu reduzieren, muss man den Müll reduzieren. Auf der anderen Seite müssen Sie nicht mit einem größeren Heap beginnen, um mehr zuweisen zu können. Wenn Sie während dieser "langen Verarbeitung" keinen HEAP-Speicher mehr haben, weist das System mehr HEAP für Sie zu, und dieser Vorgang ist für Sie zu 100% transparent. – Budius

Antwort

0

Verwendung in Ihrem Mainifast.xml dieses Attribut

android:largeHeap="true" 
+0

Danke. Aber ich habe bereits genug Heap-Größe: 'getMemoryClass()' zeigt '48MB'. Aber vor den GC-Calls habe ich nur ca. 5MB verwendet. – mortalis

Verwandte Themen