Speicherverbrauch

  • Also nochmal zusammenfassend:
    1. Die Größe des Speichers, der angefordert und nicht freigegeben wird, hängt von der Größe des Arrays für die Listenelemente des Listviews ab.
    2. Es passiert auch bei Displays, die kein Listview haben, sondern nur einfache Buttons und Editfelder.
    ( ich habs mit einem einfachen Einstellungsdialog probiert, 3 Buttons, 5 Editfelder und ein paar Beschriftungen, und da passiert es auch ).


    Da die Anzahl der darzustellenden Listitems der Anzahl der Arrayelemente enspricht, nehme ich mal an, es passiert generell beim Erzeugen der Steuerelement (Buttons, Listitems ) usw aus den Resourcen und das war ja auch deine anfängliche Vermutung.


    Aber : Egal was ich jetzt benutze ( ViewFlipper, Fragmente, separate Apps, Eine App und SetContentView u.s.w. ......
    Es werden immer Steuerelemente aus Resourcen "geholt", also wird immer Speicher verbraucht und nicht freigegeben, und kann ich machen was ich will, mehrere Displays gehen bei Android grundsätzlich nicht, weil irgendwann der Speicher aus dem Ruder läuft.


    Es ist nur so: Bei mir ist es nur aufgefallen, weil ich teilweise EXTREM VIELE Steuerelemente habe, und somit auch immer viel Speicher angefordert wird. Das wird normalerweise bei anderen Usern nicht der Fall sein, und darum ist es vielleicht noch niemandem aufgefallen.

  • noch mal ich habe dich gefragt zu wieviel Prozent der Heap voll ist.
    nochmal frage ich nicht.


    ich hoffe immer noch das du nicht mit eclipse arbeitest.


    mein Programm hast du dir bestimmt auch nicht angesehen und getestet.
    dann würdest du sehen wie sich der GC verhält.

  • Zum Thema Heap: Was nützt diese Antwort, bzw. welche Schlüsse ziehst du aus dieser Info . ;)
    Ich sehe da den Zusmmenhang mit dem Problem nicht.


    Nein, ich verwende Android Studio und das mit dem Speicher sehe ich im Profiler.
    Ich müsste erstmal gucken, wie man im Emulator die Heapgröße sehen kann, bzw ob das für einen Emulator, der auf einem PC läuft , überhaupt sinn macht. Bisher habe ich nix gesehen, wo man es erkennen kann.


    Wie sich ein Garbage Collector verhält, weiß ich.
    Das ist auch irrelevant.
    Er müsste entweder zyklisch vom System aufgerufen werden , oder bei bestimmten Ereignissen ( wie zu Beispiel wen eine App zerstört wird) und dann Speicher, der nicht mehr referenziert wird freigeben.
    Genau das macht er aber nicht, und das kann zwei Ursachen haben:
    1. Er wird gar nicht aufgerufen ( habe ich ausgeschlossen, weil ich ihn testweise selbst aufgerufen habe ( System.gc() ).
    und der Speicher ist trotzdem noch belegt.
    2. Bleibt nur Möglichkeit 2, der GC erkennt nicht, das der Speicher nicht mehr verwendet wird.
    Also muss man dafür sorgen, das er es erkennt.
    Ich habe gefragt, ob es eine Möglichkeit wie bei C gibt (new und delete).
    Gibts bei Java nicht.
    Du sagtest, man solle die Objektzeiger auf Null setzen.
    Hab ich gemacht, hilft auch nicht.
    Es hat nicht geholfen, weil es gar nicht der von mir allokierte Speicher ist, der das Problem verursacht, also hilft es auch nicht, den von mir allokieretn Speicher auf null zu setzen oder sonstwas damit anzustellen.


    Das Einzige, was helfen wird ist, wenn es eine Möglichkeit gäbe, die aus den Resourcen "geholten" Steuerelemente wieder zu zerstören.

  • Wenn du dir mein Beispiel angesehen hattest wüsstet du wie der GC arbeitet und was du machen kannst um den GC dazu zubringen den Speicher aufzuräumen wann du willst und nicht wann er will.
    System.gc() ist Standard Java und nicht Android.




    Zitat

    Es hat nicht geholfen, weil es gar nicht der von mir allokierte Speicher ist, der das Problem verursacht, also hilft es auch nicht, den von mir allokieretn Speicher auf null zu setzen oder sonstwas damit anzustellen.

    Was ist mit deinem Adapter da wirst du einiges verbrauchen.



    Zitat


    Wie sich ein Garbage Collector verhält, weiß ich.
    Das ist auch irrelevant.

    mit sicherheit nicht sonst wärst du nicht hier.



    Zitat

    Er müsste entweder zyklisch vom System aufgerufen werden , oder bei bestimmten Ereignissen ( wie zu Beispiel wen eine App zerstört wird) und dann Speicher, der nicht mehr referenziert wird freigeben.

    so einfach ist es eben nicht und auch versions abhängig.
    aber du glaubst es hat nicht.

  • Ich habe jetzt 2 Stunden gesucht, ich weiß nicht, wie ich die Belegung des Heaps in Prozent rausbekomme.
    Ich sehe im Profiler nur, das meine App mit einem Verbrauch von 36MB startet, und das bei den Wechseln der Fenster immer etwas zwischen 100 - 500 KB dazu kommen ( Also von A nach B kommt was hinzu, und von B nach A zurück auch wieder.


    Oben im Profiler ist ne gestrichelte Linie bei 64MB. Wenn das die Heapgröße ist, dann wäre also bei Start der verwendete Heap ca. 50%.


    Und zum GC. Das glaube ich schon, das da spezielle Feinheiten sind.
    Ich habe ja auch nur gesagt, was er im Prinzip macht.
    Aufgerufen muss er werden, sonst macht das keinen Sinn, dann wäre er toter Code.
    Und unbenutzen Speicher freigeben macht er auch, und vermutlich auch eine Defrargmentierung


    Das Einzige, was ich mir noch vorstellen kann, wäre, das er erst dann Speicher freigibt, wenn keiner mehr da ist.
    In diesem Fall wäre mein hochschukeln des Speichers normal.
    Dagegen spricht aber, das meine App auf dem Handy zum Freeze desselben führt.


    Man kann den GC auch vom Profile Menü aus aufrufen. Wenn ich das mache, wird zwar etwas freigegeben, aber nicht alles.
    Das Hochschaukeln geht weiter.


    Hier ein Beispiel:
    A gestartet : 36,0 MB
    A startet B : 36,6 MB
    B zurück zu A 36,8 MB
    A startet B: 36,9 MB
    B zurück zu A 37,0 MB
    A startet B 37,1 MB


    u.s.w.


    Garbage Collector per Menü aufrufen : 36,7 MB ( also 700MB nicht freigegeben )


    Wieder wie oben weitergetestet:
    Speicher steigt wieder wie oben an.


    Garbage Collector wieder per Menü aufgerufen 38,1 MB


    u.s.w.


    Der Speicher steigt und steigt.



    Also stelle ich die Frage mal anders rum.
    Wenn der Heap bei Programmstart 50% belegt ist, was sagt das dann aus ?


    Was muss ich bei Android /Java machen, damit der Speicher, den meine Steuerelemente belegen, wieder freigegeben wird ?


    Selbst wenn ich genau wüsste, wie der GC funktioniert, nützt es mir nix, wenn es keine Möglichkeit gibt, ihn so zu nutzen, das der unbenutzte Speicher freigegeben wird. Und genau das ist mein Problem bzw meine Frage

  • Das Freigeben des Speichers findet bei ca 70% statt aber meistens erst dann wenn Speicher angefordert wird.


    Wenn beim App Start schon 50% belegt ist das schon viel.


    Wie du den Speicher sehen kannst und wie du den GC auch selber auslösen kannst, kannst du dir in meinen Code ansehen.



    Post NR.18 wenn du das nicht ansiehst und testest deine Schuld.




    Runtime.getRuntime().gc();


    https://stackoverflow.com/ques…thod-in-ondestroy-of?rq=1





    Hier ein Beispiel:
    A gestartet : 36,0 MB
    A startet B : 36,6 MB
    B zurück zu A 36,8 MB
    A startet B: 36,9 MB
    B zurück zu A 37,0 MB
    A startet B 37,1 MB



    Ist ja nicht viel was da verbraucht wird.

  • Laut Doku soll das das Gleiche sein . System.rc ruft intern auch Runtime.getRuntime().gc(); auf.


    Ich weiß jetzt allerdings gar nicht, ob das Problem überhaupt noch eines ist.
    Enstanden ist es, als ich noch für jedes Display eine eigene Activity benutzt habe. Der Speicherbedarf war extrem und da ist dann mein Handy "eingefroren".
    Ich dachte, das Problem wäre weg, wenn ich nur eine einzige Activity habe.
    Also habe ich meine App umgeschrieben und NICHT auf dem Handy sonderrn erstmal im Emulator getestet, wie es da mit dem Speicher ist.
    Mit der einzelnen Activity war der Verbrauch zwar deutlich geringer, aber er stieg wie in meinem letzten Post geschrieben immer noch an, und ich dachte, das sei bestimmt nicht normal.
    Wenn du aber sagst, das der GC etwa bei 70% erst Speicher freigibt, dann kann es gut sein, das das Verhalten meiner App doch normal ist.


    Ich werde es ja sehen, wenn sie wieder funktionsfähig ist.
    Ich knacke da nämlich noch an einem anderen ünlösbaren Problem, aber das ist ein andere Thread.


    Also sage ich erstmal vielen Dank für deine Mühe und Geduld.

  • Zitat

    Laut Doku soll das das Gleiche sein . System.rc ruft intern auch Runtime.getRuntime().gc(); auf.

    Wo steht das bitte Quelle angeben.


    Auch wenn es in den meistens Java Dokus so steht. Ist es doch immer von der JVM abhängig.
    Jede JVM setzt das ein wenig anders um.
    Deshalb beziehe dich immer auf die Android Doku. Da haben wir die Dalvik JVM.


    https://developer.android.com/…s/verifying-apps-art.html
    https://developer.android.com/reference/java/lang/System#gc()



    das steht das es System.gc() fast gleichwertig ist zu Runtime.getRuntime().gc() is.
    aber eben nur Fast.
    Beim Test siehst du die Unterschiede.




    Das es nicht das gleiche Verhalten ist kannst du in meiner app sehen und testen. Hast du das überhaupt?

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!