2015-12-14 1 views
7

Ich habe Schwierigkeiten, ein mögliches Speicherleck zu finden. Ich habe eine Aktivität, die im Hintergrund einige schwere Arbeit leistet.Wie initiiert das Android Studio den Garbage Collector und wie funktioniert es?

Nach einigen Aufgaben verbraucht die App zu viel Speicher. Es scheint, dass es nicht richtig aufgeräumt wird.

Dies ist die Aktivität in den Auslieferungszustand:

enter image description here

Wenn ich die Aufgabe ausführen, die die Aktivität tut, mehr und mehr Speicher zugeordnet ist.

Aktivität nach einiger Arbeit: enter image description here

Zuerst dachte ich, das ein Speicherproblem sein muss, bewirken, dass der GC nicht richtig den Speicher freizugeben. Soweit ich weiß, kann der GC den Speicher freigeben, wenn keine Referenz mehr zu den Objekten vorhanden ist. Ist das korrekt?

Jetzt kommt der Teil, der mich verwirrt:

Wenn ich die GC von Android Studio ausführen, wird der Speicher richtig und meine Tätigkeit geschlossen wird nie gereinigt. Ich muss nur den Android Studio GC verwenden, wenn zu viel Speicher zugewiesen ist. enter image description here

Das ist das, was ich meine:

enter image description here

allgemein In der Frage ist:

Warum richtig den Speicher der Android Studio GC aufzuräumen und warum nicht der Fall ist funktioniert es richtig mit dem automatischen android GC?

Ich weiß, das ist eine ziemlich allgemeine Frage. Ich möchte nur wissen, ob es verschiedene Arten von Garbage Collections oder ähnliches gibt.

Auch der Aufruf System.gc(); bereinigt den Speicher nicht ordnungsgemäß.

Zusätzliche Information:

Moto G 2nd gen

Android 5.0.2.

+0

"Manchmal schließt die Aktivität oder die App. Ich dachte, es könnte durch Speicherprobleme verursacht werden." Wenn die App b/c stirbt, wird nicht genügend Speicher zur Verfügung gestellt. Sie erhalten eine Out-of-Memory-Ausnahme, die Sie in Logcat deutlich sehen können. Meine Vermutung ist, dass Ihre App aus einem anderen Grund abstürzt. Versuchen Sie, Logcat zu sehen, um zu sehen, was der Absturzgrund ist. – Shmuel

+1

Der gleichzeitige GC führt nur eine Teilerfassung durch, um keine merklichen Pausen zu verursachen. Expliziter GC, wie der von Studio ausgelöste, macht einen vollständigen GC-Sweep. Einige lesen: https://source.android.com/devices/tech/dalvik/gc-debug.html – laalto

+0

@Shmuel Es gibt keine Ausnahmen. Nicht einmal Warnungen. – FlanschiFox

Antwort

2

Vielleicht können Sie versuchen, in Ihrem schweren Verarbeitungscode regelmäßig irgendwo in regelmäßigen Abständen aufzurufen?

+0

Sorry, ich habe das vergessen. Das habe ich schon probiert und es hat nicht funktioniert. – FlanschiFox

+0

Wenn wirklich ein Speicherleck vorhanden ist, wird der Aufruf von System.gc() nicht helfen b/c der Speicher wird immer noch über eine Referenz irgendwo im Code gehalten. – Shmuel

+0

@Shmuel Wahr, aber OP sagt, die App stürzt nicht ab, wenn er den GC-Knopf im Android-Studio drückt, was, wie ich mir vorstelle, einen Aufruf an 'System.gc()' macht, daher mein Vorschlag. –

4

Speicherlecks können aus verschiedenen Gründen auftreten. Ein häufiger Grund sind Bitmaps, die nicht korrekt recycelt werden. Andere Samen von Speicherlecks behalten den Kontext in Objekten. Beispielsweise starten Sie eine asynchrone Aufgabe und übergeben einen Kontext, weil Sie ihn später benötigen. Während die asynchrone Task ausgeführt wird, behält sie einen Verweis auf den Kontext und so befindet sich die gesamte Aktivität im Speicher. Dies ist auch sehr häufig bei anonymen und inneren Klassen, die einen Verweis auf die Elternklasse haben, die normalerweise ein Fragment oder eine Aktivität ist.

Ich empfehle Ihnen, die Bibliothek Leak Canary zu verwenden, um Speicherlecks zu erkennen und die Android-Tools zu verwenden, um die Zuordnungen zu verfolgen, um genau zu ermitteln, wo das Speicherleck passiert.

+0

Danke für die Antwort. Sie erwähnten häufige Gründe, wie Speicherlecks auftreten. Im Grunde ist es alles nur ein Vorbehalt der verbleibenden Referenzen. Aber in meinem Fall bereinigt der Android Studio GC-Anruf alles richtig. Also, wenn es einige seltsame Referenzen geben sollte, sollte der GC nicht in der Lage sein, sie richtig zu reinigen? – FlanschiFox

+0

Nicht genau. Sie können eine Aktivität beenden, behalten jedoch für einige Sekunden eine Referenz. Wenn Sie GC nach ein paar Sekunden ausführen, wird der Speicher gelöscht. Ich war mit Situationen konfrontiert, in denen ich von mehreren Aktivitäten zurückging und einen Speicherüberlauf hatte, weil vielleicht eine Bitmap recycelt wurde und der GC diesen Speicher freigab und so der Speicher nicht mehr verfügbar war. Standardmäßig gibt der GC keinen Speicher frei, wenn dies nicht erforderlich ist (die maximal zulässige Speichermenge wird nicht erreicht). Es kann auch Ihr anderes Problem sein. – jorgemf

+0

Ich bin froh, dass ich diesen Thread sehe und es ist ziemlich neu. Haben Sie @oberflansch den Grund gefunden, warum der GC des Android-Studios besser funktioniert? Ich arbeite an der gleichen Situation, die die Anwendung aus dem Speicher wirft und das Programm abstürzt. Eine Sache, die ich in meiner App fand, die das Speicherproblem verursachte, war, weil alle PNG-Bilder, die ich in den Betriebsmitteln benutze, zu groß sind. Ich frage mich, warum der Android GC selbst nicht nach einer Aktivität geschlossen ist, selbst alle Referenzen in der Klasse sind eigentlich geschlossen ... der Speicher erhöht sich jedes Mal, wenn eine neue Aktivität erstellt wird, bis es stirbt –

Verwandte Themen