Ich entwickle derzeit eine Xamarin.Android App, die eine Menge von Aktivitäten enthält, arbeiten mit einer API, die Bilder und manchmal riesige Listen von Objekten zurückgeben, so muss ich auf Speicher zu kümmern Vermeiden Sie OOM.Speicherleck mit einfachen Aktivitäten Navigation
Aber es gelang mir schließlich, einige zu haben, als ich anfing, mit Bitmaps zu arbeiten. Zuerst dachte ich, es wäre wegen dieser Bitmaps, also habe ich ein paar Tests gemacht. Und es scheint, dass es nicht ist. Ich habe die API deaktiviert, also arbeite ich mit leeren Listen von Objekten und ohne Bilder. Und es ist mir immer noch gelungen, den Speicherverbrauch meiner App verrückt zu machen, um schließlich zu stürzen.
Da ich Xamarin Profiler auf Visual Studio nicht installieren kann (keine Ahnung warum, aber nicht das Hauptproblem hier), installierte ich eine App auf meinem Gerät (das ist ein OnePlus One), genannt Intel Performance Viewer ist in der Lage, die RAM-Nutzung des Geräts in Echtzeit zu überwachen. Ich starte meine App und sagen wir, die Speicherauslastung beträgt insgesamt 1,1 GB Speicherplatz. Ich klicke auf eine Schaltfläche, die eine Liste von Objekten anzeigen soll, aber da die API inaktiv ist, ist die Liste leer. Die Aktivität enthält also eine benutzerdefinierte Appbar, zwei Schaltflächen, eine leere Listenansicht und einen Text mit der Aufschrift "Liste ist leer". Der RAM-Verbrauch stieg von ca. 30MB, als dieser Vorgang aufgerufen wurde. Dann drücke ich meine Zurück-Taste, die ein Finish() ruft; auf die Aktivität, dann bin ich wieder am Main. Und der RAM-Verbrauch sinkt von gleich, ein oder zwei MB.
Dann, wenn ich diese Aktivität wieder beginne, wird es anfangen, essen 30 MB mehr, und wenn ich zwischen Aktivitäten wie diesem wechseln, wird es schließlich zu OOME führen.
Ich habe in meinen Geräteentwickler-Optionen versucht, "Aktivitäten nicht zu behalten", und es scheint, als würde es mehr RAM freigeben (wie logisch), aber immer noch nicht alles. Ich muss viel mehr wechseln, bevor ich den Speicher verliere, aber das Problem ist immer noch da.
Soll Finish nicht alle in der Aktivität enthaltenen Daten im Garbage Collector ablegen? Ich habe versucht, GC.Collect() zu machen; in meinem OnDestroy, kein Effekt.
Ich weiß nicht, ob ich falsch verstehe, wie Speicher auf Android funktioniert, wie ich ziemlich neu in Mobile Dev bin, aber das gibt mir Kopfschmerzen. Irgendeine Hilfe ?
Danke!
Edit: das ist was ich bekomme, wenn es OOM geht.
05-23 10:15:37.973 D/dalvikvm(5049): GC_FOR_ALLOC freed 1587K, 3% free 248825K/256263K, paused 22ms, total 23ms
05-23 10:15:37.973 I/dalvikvm-heap(5049): Grow heap (frag case) to 245.840MB for 2908172-byte allocation
05-23 10:15:38.029 D/dalvikvm(5049): GC_CONCURRENT freed 127K, 2% free 2515
37K/256263K, paused 10ms+10ms, total 52ms
05-23 10:15:38.077 D/dalvikvm(5049): GC_FOR_ALLOC freed 74K, 2% free 251463K/256263K, paused 23ms, total 23ms
05-23 10:15:38.077 I/dalvikvm-heap(5049): Forcing collection of SoftReferences for 11632652-byte allocation
05-23 10:15:38.105 D/dalvikvm(5049): GC_BEFORE_OOM freed 306K, 2% free 251156K/256263K, paused 29ms, total 29ms
05-23 10:15:38.105 E/dalvikvm-heap(5049): Out of memory on a 11632652-byte allocation.
05-23 10:15:38.105 I/dalvikvm(5049): "main" prio=5 tid=1 RUNNABLE
05-23 10:15:38.105 I/dalvikvm(5049): | group="main" sCount=0 dsCount=0 obj=0xa62704b0 self=0xb7c7b510
05-23 10:15:38.105 I/dalvikvm(5049): | sysTid=5049 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=-1217084352
05-23 10:15:38.105 I/dalvikvm(5049): | schedstat=(7886788399 5740305249 19539) utm=596 stm=192 core=0
05-23 10:15:38.117 E/mono-rt (5049): =================================================================
05-23 10:15:38.117 E/mono-rt (5049): Got a SIGSEGV while executing native code. This usually indicates
05-23 10:15:38.117 E/mono-rt (5049): a fatal error in the mono runtime or one of the native libraries
05-23 10:15:38.117 E/mono-rt (5049): used by your application.
05-23 10:15:38.117 E/mono-rt (5049): =================================================================
05-23 10:15:38.117 E/mono-rt (5049):
05-23 10:15:38.117 F/libc (5049): Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread 5049
Ich habe bereits einige davon gelesen, und was ich daraus verstanden habe (vielleicht habe ich mich geirrt), ist, dass wenn eine Aktivität beendet ist, sie im Speicher gehalten wird, um sie schneller neu zu starten, aber wenn wenig Speicher vorhanden ist verfügbar. Aber es scheint nie zu passieren, Speicher geht hoch, bis es die maximale Heap-Größe erreicht. Ich füge ein bisschen von dem Stack-Trace hinzu, den ich habe, als ich diesen OOM bekam. – YumeYume