Erkennung von Anwendungshaufen in Android

Wie erkennst du programmgesteuert die für eine Android-App verfügbare Anwendungshaufengröße?

Ich habe gehört, dass es eine Funktion gibt, die dies in späteren Versionen des SDK tut. Auf jeden Fall suche ich nach einer Lösung, die für 1,5 und höher funktioniert.

  • Vermeiden Sie, dass ein DialogFragment entlassen wird, wenn die Suchtaste gedrückt wird - Android
  • Laden Sie apk Datei von S3 mit DownloadManager herunter
  • Wann ist onRestoreInstanceState?
  • Android Studio - Gradle
  • Halten Sie die Dinge dezentral Android
  • Hochauflösender Screenshot in Android
  • Wie man eine Anwendung programmgesteuert durch Tastenklick beenden kann
  • Android: Wie kann ich einen Kontakt zur SIM mit dem SDK hinzufügen?
  • Aufnahmen von Open GL ES auf Android
  • Android Studio gradle 2.1.3 Ausgabe
  • Statische Variablen, wie ist ihre Lebensdauer?
  • Verfügt der Android-Studio-Layout-Editor über benutzerdefinierte View-Eigenschaften?
  • 9 Solutions collect form web for “Erkennung von Anwendungshaufen in Android”

    Es gibt zwei Möglichkeiten, über Ihre Phrase "Anwendung Heap Größe verfügbar" zu denken:

    1. Wie viel Haufen kann meine App verwenden, bevor ein schwerer Fehler ausgelöst wird? Und

    2. Wie viel Haufen sollte meine Anwendung verwenden, angesichts der Einschränkungen der Android OS-Version und Hardware des Gerätes des Benutzers?

    Es gibt eine andere Methode zur Bestimmung jeder der oben genannten.

    Für Punkt 1 oben: maxMemory()

    Die aufgerufen werden können (z. B. in der onCreate() -Methode Ihrer Hauptaktivität) wie folgt:

     Runtime rt = Runtime.getRuntime(); long maxMemory = rt.maxMemory(); Log.v("onCreate", "maxMemory:" + Long.toString(maxMemory)); 

    Diese Methode sagt Ihnen, wie viele ganze Bytes von Haufen Ihre App erlaubt ist, zu verwenden.

    Für Punkt 2 oben: getMemoryClass()

    Die wie folgt aufgerufen werden können:

     ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); int memoryClass = am.getMemoryClass(); Log.v("onCreate", "memoryClass:" + Integer.toString(memoryClass)); 

    Diese Methode sagt Ihnen etwa, wie viele Megabyte von Haufen Ihre App sollte verwenden, wenn es richtig respektiert werden die Grenzen des aktuellen Gerätes, und der Rechte der anderen Apps zu laufen, ohne wiederholt in die onStop() / onResume() Zyklus, wie sie sind grob aus dem Gedächtnis gespült, während Ihre Elephantine App nimmt ein Bad in der Android-Jacuzzi.

    Diese Unterscheidung ist nicht eindeutig dokumentiert, soweit ich weiß, aber ich habe diese Hypothese auf fünf verschiedenen Android-Geräten getestet (siehe unten) und habe zu meiner Zufriedenheit bestätigt, dass dies eine korrekte Interpretation ist.

    Für eine Bestandsversion von Android wird maxMemory() in der Regel über die gleiche Anzahl von Megabyte zurückkehren, wie in getMemoryClass() (dh etwa eine Million Mal der letztere Wert).

    Die einzige Situation (von der ich weiß), für die die beiden Methoden divergieren kann, ist auf einem verwurzelten Gerät mit einer Android-Version wie CyanogenMod, die es dem Benutzer ermöglicht, manuell auszuwählen, wie groß eine Heapgröße für jede App erlaubt werden soll. In CM wird diese Option beispielsweise unter "CyanogenMod Einstellungen" / "Performance" / "VM Heap Size" angezeigt.

    HINWEIS: BEARBEITEN, DASS EINSTELLUNG DIESER WERT MANUELL KANN IHR SYSTEM MESSEN, INSBESONDERE, wenn Sie einen kleineren Wert auswählen, als es für Ihr Gerät normal ist.

    Hier sind meine Testergebnisse, die die von maxMemory() und getMemoryClass() Werte für vier verschiedene Geräte mit CyanogenMod getMemoryClass() , wobei jeweils zwei verschiedene (manuell eingestellte) Heap-Werte verwendet werden:

    • G1:
      • Mit VM Heap Größe auf 16MB eingestellt:
        • MaxMemory: 16777216
        • GetMemoryClass: 16
      • Mit VM Heap Größe auf 24MB eingestellt:
        • MaxMemory: 25165824
        • GetMemoryClass: 16
    • Moto Droid:
      • Mit VM Heap Größe auf 24MB eingestellt:
        • MaxMemory: 25165824
        • GetMemoryClass: 24
      • Mit VM Heap Größe auf 16MB eingestellt:
        • MaxMemory: 16777216
        • GetMemoryClass: 24
    • Nexus One:
      • Mit VM Heap Größe auf 32MB eingestellt:
        • MaxMemory: 33554432
        • GetMemoryClass: 32
      • Mit VM Heap Größe auf 24MB eingestellt:
        • MaxMemory: 25165824
        • GetMemoryClass: 32
    • Viewsonic GTab:
      • Mit VM Heap Größe auf 32 gesetzt:
        • MaxMemory: 33554432
        • GetMemoryClass: 32
      • Mit VM Heap Größe auf 64 gesetzt:
        • MaxMemory: 67108864
        • GetMemoryClass: 32

    Zusätzlich zu den oben genannten habe ich auf einer Novo7 Paladin Tablette mit Eiscreme Sandwich getestet. Dies war im Wesentlichen eine Bestandsversion von ICS, außer dass ich das Tablet durch einen einfachen Prozess verwurzelt habe, der das gesamte Betriebssystem nicht ersetzt und insbesondere keine Schnittstelle zur Verfügung stellt, die es erlaubt, die Heapgröße manuell einzustellen.

    Für dieses Gerät sind hier die Ergebnisse:

    • Novo7
      • MaxMemory: 62914560
      • GetMemoryClass: 60

    Auch (pro Kishore in einem Kommentar unten):

    • HTC ein x
      • MaxMemory: 67108864
      • GetMemoryClass: 64

    Und (nach Akauppis Kommentar):

    • Samsung Galaxy Core Plus
      • MaxMemory: (Nicht im Kommentar angegeben)
      • GetMemoryClass: 48
      • GroßeMemoryClass: 128

    Ein Kommentar von cmcromance:

    • Galaxy S3 (Jelly Bean) großer Haufen
      • MaxMemory: 268435456
      • GetMemoryClass: 64

    Und (per tencent's Kommentare):

    • LG Nexus 5 (4.4.3) normal
      • MaxMemory: 201326592
      • GetMemoryClass: 192
    • LG Nexus 5 (4.4.3) großer Haufen
      • MaxMemory: 536870912
      • GetMemoryClass: 192
    • Galaxy Nexus (4.3) normal
      • MaxMemory: 100663296
      • GetMemoryClass: 96
    • Galaxy Nexus (4.3) großer Haufen
      • MaxMemory: 268435456
      • GetMemoryClass: 96
    • Galaxy S4 Play Store Edition (4.4.2) normal
      • MaxMemory: 201326592
      • GetMemoryClass: 192
    • Galaxy S4 Play Store Edition (4.4.2) großer Haufen
      • MaxMemory: 536870912
      • GetMemoryClass: 192

    Andere Geräte

    • Huawei Nexus 6P (6.0.1) normal
      • MaxMemory: 201326592
      • GetMemoryClass: 192

    Ich habe diese beiden Methoden nicht mit dem speziellen Android getestet: bigHeap = "true" Manifest Option seit Honeycomb, aber dank cmcromance und tencent haben wir einige Probe largeHeap Werte, wie oben berichtet.

    Meine Erwartung (die von den oben erwähnten HighHeap-Nummern unterstützt werden soll) wäre, dass diese Option einen ähnlichen Effekt hätte, wie man den Haufen manuell über ein verwurzeltes Betriebssystem maxMemory() – dh es würde den Wert von maxMemory() beim Verlassen von getMemoryClass() allein. Es gibt eine andere Methode, getLargeMemoryClass (), die angibt, wie viel Speicher für eine App mit der largeHeap-Einstellung zulässig ist. Die Dokumentation für getLargeMemoryClass () gibt an, "die meisten Anwendungen sollten nicht diese Menge an Speicher benötigen und sollten stattdessen mit dem getMemoryClass () -Grenze bleiben."

    Wenn ich richtig erraten habe, dann würde die Verwendung dieser Option die gleichen Vorteile (und Gefahren) haben, wie sie den von einem Benutzer, der den Heap über ein verwurzeltes Betriebssystem heruntergeladen hat, verfügbar gemacht hat (dh wenn dein App den zusätzlichen Speicher verwendet, Es wird wahrscheinlich nicht so schön spielen mit was auch immer andere apps der Benutzer gleichzeitig läuft).

    Beachten Sie, dass die Speicherklasse anscheinend kein Vielfaches von 8 MB sein muss.

    Wir können aus dem obigen sehen, dass das getMemoryClass() Ergebnis für eine gegebene Geräte / OS-Konfiguration unverändert ist, während sich der maxMemory () – Wert ändert, wenn der Heap vom Benutzer unterschiedlich gesetzt wird.

    Meine eigene praktische Erfahrung ist, dass auf der G1 (die eine Speicherklasse von 16 hat), wenn ich manuell 24MB als Heap-Größe auswählen kann, kann ich ohne Fehlerstellung laufen, auch wenn meine Speicherverwendung erlaubt ist, bis zu 20MB zu driften (vermutlich könnte es Gehen so hoch wie 24MB, obwohl ich das nicht ausprobiert habe). Aber andere ähnlich groß-ish apps können aus dem Gedächtnis als Ergebnis meiner eigenen App Schweinheit gerötet werden. Und umgekehrt kann meine App aus dem Speicher gerötet werden, wenn diese anderen Wartungs-Apps vom Benutzer in den Vordergrund gebracht werden.

    So kannst du nicht über die von maxMemory() spezifizierte Speichermenge maxMemory() . Und du solltest versuchen , innerhalb der von getMemoryClass() angegebenen Grenzen zu bleiben. Ein Weg, dies zu tun, wenn alles andere fehlschlägt, könnte es sein, die Funktionalität für solche Geräte in einer Weise zu begrenzen, die Speicher bewahrt.

    Schließlich, wenn Sie planen, über die Anzahl der Megabyte in getMemoryClass() spezifiziert zu gehen, würde mein Rat sein, lange und hart zu arbeiten, um das Speichern und Wiederherstellen des Status Ihrer App zu machen, so dass die Benutzererfahrung praktisch ununterbrochen ist, wenn ein onStop() / onResume() Zyklus auftritt.

    In meinem Fall, aus Gründen der Leistung beschränke ich meine App auf Geräte, die 2.2 und höher laufen, und das bedeutet, dass fast alle Geräte, die meine App laufen, eine MemoryClass von 24 oder höher haben werden. So kann ich entwerfen bis zu 20MB Haufen und fühle mich ziemlich zuversichtlich, dass meine App wird nett mit den anderen apps der Benutzer kann zur gleichen Zeit laufen.

    Aber es wird immer ein paar verwurzelte Benutzer geben, die eine 2.2 oder höhere Version von Android auf ein älteres Gerät geladen haben (zB ein G1). Wenn du einer solchen Konfiguration begegnet bist, solltest du idealerweise deinen Gedächtnis nutzen, auch wenn maxMemory() dir sagt, dass du viel höher als die 16MB gehen kannst, die getMemoryClass() dir sagt, dass du dir zielen solltest . Und wenn Sie nicht zuverlässig sicherstellen können, dass Ihre App in diesem Budget leben wird, dann stellen Sie sicher, dass onStop() / onResume() nahtlos arbeitet.

    getMemoryClass() , wie von Diane Hackborn (hackbod) oben angegeben, ist nur zurück auf API Level 5 (Android 2.0), und so, wie sie berät, können Sie davon ausgehen, dass die physische Hardware von jedem Gerät läuft eine frühere Version der OS ist entworfen, um optimal zu unterstützen apps, die einen Haufenraum von nicht mehr als 16MB einnehmen.

    Im Gegensatz dazu ist maxMemory() nach der Dokumentation bis hin zur API-Ebene 1. maxMemory() , auf einer Pre-2.0-Version, wird wahrscheinlich einen 16MB-Wert zurückgeben, aber ich sehe das in meinem (viel Später) CyanogenMod Versionen kann der Benutzer einen Heap-Wert wählen, der so niedrig wie 12MB ist, was vermutlich zu einer niedrigeren Heap-Grenze führen würde, und so würde ich vorschlagen, dass Sie den maxMemory() -Wert auch für Versionen des Betriebssystems vor dem Test maxMemory() 2,0 Möglicherweise muss man sogar ablehnen, in dem unwahrscheinlichen Fall zu laufen, dass dieser Wert noch niedriger als 16MB eingestellt ist, wenn man mehr als maxMemory() anzeigt, ist erlaubt.

    Die offizielle API ist:

    Dies wurde in 2.0 eingeführt, wo größere Speichergeräte erschienen sind. Sie können davon ausgehen, dass Geräte, die vorherige Versionen des Betriebssystems ausführen, die ursprüngliche Speicherklasse (16) verwenden.

    Debug.getNativeHeapSize() wird den Trick machen, denke ich. Es ist schon seit 1.0 da.

    Die Debug Klasse hat viele gute Methoden für die Verfolgung von Zuweisungen und anderen Leistungsanforderungen. Auch wenn Sie eine Low-Memory-Situation erkennen müssen, schauen Sie sich Activity.onLowMemory() .

    Hier ist, wie Sie es tun:

    Die maximale Heap-Größe, die die App verwenden kann:

     Runtime runtime = Runtime.getRuntime(); long maxMemory=runtime.maxMemory(); 

    Wie viel von dem Heap deine App benutzt:

     long usedMemory=runtime.totalMemory() - runtime.freeMemory(); 

    Wie viel von dem Heap deine App jetzt nutzen kann (verfügbarer Speicher):

     long availableMemory=maxMemory-usedMemory; 

    Und um jedes von ihnen schön zu formatieren, kannst du:

     String formattedMemorySize=Formatter.formatShortFileSize(context,memorySize); 

    Dies gibt die maximale Heapgröße in Bytes zurück:

     Runtime.getRuntime().maxMemory() 

    Ich verwendete ActivityManager.getMemoryClass () aber auf CyanogenMod 7 (ich habe es nicht anderswo getestet), gibt es falschen Wert zurück, wenn der Benutzer die Haufengröße manuell einstellt.

    Asus Nexus 7 (2013) 32Gig: getMemoryClass () = 192 maxMemory () = 201326592

    Ich habe den Fehler gemacht, mein Spiel auf dem Nexus 7 zu prototypen, und dann entdeckte es aus dem Gedächtnis fast sofort auf meiner Frau generischen 4.04 Tablette (Gedächtnis 48, maxmemory 50331648)

    Ich muss mein Projekt neu strukturieren, um weniger Ressourcen zu laden, wenn ich die Speicherklasse festlege.
    Gibt es einen Weg in Java, um die aktuelle Haufengröße zu sehen? (Ich sehe es eindeutig in der logCat beim Debuggen, aber ich möchte einen Weg, um es in Code zu sehen, um zu passen, wie wenn currentheap> (maxmemory / 2) entladen hochwertige Bitmaps laden niedrige Qualität

    Meinst du programmatisch, oder einfach, während du dich entwickelst und debugst? Wenn die letzteren, können Sie sehen, dass Informationen aus der DDMS-Perspektive in Eclipse. Wenn dein Emulator (evtl. sogar physikalisches Telefon, das eingesteckt ist) läuft, wird es die aktiven Prozesse in einem Fenster auf der linken Seite auflisten. Sie können es auswählen und es gibt eine Option, um die Heap-Zuweisungen zu verfolgen.

     Runtime rt = Runtime.getRuntime(); rt.maxMemory() 

    Wert ist b

     ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); am.getMemoryClass() 

    Wert ist MB

    Einige Operationen sind schneller als Java Haufen Space Manager. Verzögerungsvorgänge für einige Zeit können Speicherplatz freigeben. Sie können diese Methode verwenden, um Heap-Größenfehler zu entkommen:

     waitForGarbageCollector(new Runnable() { @Override public void run() { // Your operations. } }); /** * Measure used memory and give garbage collector time to free up some * space. * * @param callback Callback operations to be done when memory is free. */ public static void waitForGarbageCollector(final Runnable callback) { Runtime runtime; long maxMemory; long usedMemory; double availableMemoryPercentage = 1.0; final double MIN_AVAILABLE_MEMORY_PERCENTAGE = 0.1; final int DELAY_TIME = 5 * 1000; runtime = Runtime.getRuntime(); maxMemory = runtime.maxMemory(); usedMemory = runtime.totalMemory() - runtime.freeMemory(); availableMemoryPercentage = 1 - (double) usedMemory / maxMemory; if (availableMemoryPercentage < MIN_AVAILABLE_MEMORY_PERCENTAGE) { try { Thread.sleep(DELAY_TIME); } catch (InterruptedException e) { e.printStackTrace(); } waitForGarbageCollector( callback); } else { // Памяти достаточно, выполняем операции: callback.run(); } } 
    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.