¿Cómo aumentar el tamaño de almacenamiento dinámico de una aplicación de Android?

125

Estoy escribiendo una aplicación de Android que usa varios modelos 3D. Tal modelo con texturas puede ocupar mucha memoria. Descubrí que el fabricante establece un límite en el tamaño de almacenamiento dinámico que una aplicación puede usar. Por ejemplo, mi tableta Samsung Galaxy Tab 8.9 P7310 puede ocupar 64 MB de memoria.

¿Hay alguna manera de aumentar este tamaño de memoria que una aplicación puede usar?

Cooxie
fuente

Respuestas:

210

Puede usar android: largeHeap = "true" para solicitar un tamaño de almacenamiento dinámico más grande, pero esto no funcionará en ningún dispositivo anterior Honeycomb. En dispositivos anteriores a 2.3, puede usar la clase VMRuntime, pero esto no funcionará en Gingerbread y versiones posteriores.

La única forma de tener un límite lo más grande posible es realizar tareas intensivas de memoria a través del NDK, ya que el NDK no impone límites de memoria como el SDK.

Alternativamente, solo puede cargar la parte del modelo que está actualmente a la vista y cargar el resto según lo necesite, mientras elimina las partes no utilizadas de la memoria. Sin embargo, esto puede no ser posible, dependiendo de su aplicación.

Raghav Sood
fuente
NDK se ve interesante. ¿Podría usarlo en combinación con mi código ya escrito con SDK?
cooxie
3
Eso depende completamente de qué código tienes. No soy un experto en el NDK, y solo conozco lo básico. Le recomendaría que haga esta pregunta junto con una descripción de su código en el grupo Google android-ndk, o publique una nueva pregunta sobre SO específica para esto con la etiqueta android-ndk.
Raghav Sood
Me pregunto si no podemos "simplemente" usar Unity3D como una respuesta más específica a la pregunta ("usa varios modelos 3D") ... No pude encontrar rápidamente ninguna evidencia clara sobre si la unidad usa NDK.
cregox
3
largeHeap=trueFTW
Luis Artola
2
los desarrolladores de la api de Android son realmente divertidos, son como si quisieras más Ok, solicítelo, es solo para aquellos que lo necesitan ... mientras tanto, cada desarrollador lo agrega como lo primero que debe agregar cuando la aplicación entre en producción :)
AndroidLover
110

¿Hay alguna manera de aumentar este tamaño de memoria que una aplicación puede usar?

Las aplicaciones que se ejecutan en API Nivel 11+ pueden tener android:largeHeap="true"en el <application>elemento en el manifiesto para solicitar un tamaño de almacenamiento dinámico mayor que el normal, y en getLargeMemoryClass()adelante ActivityManagerle indicarán qué tan grande es ese almacenamiento dinámico. Sin embargo:

  1. Esto solo funciona en API Level 11+ (es decir, Honeycomb y más allá)

  2. No hay garantía de cuán grande será el montón grande

  3. El usuario percibirá su solicitud de gran cantidad, ya que obligará a sus otras aplicaciones a salir de la RAM y finalizará los procesos de otras aplicaciones para liberar la RAM del sistema para que la use su gran cantidad

  4. Debido al n. ° 3, y el hecho de que espero que android:largeHeapse abuse de él, el soporte para esto puede abandonarse en el futuro, o el usuario puede ser advertido sobre esto en el momento de la instalación (por ejemplo, deberá solicitar un permiso especial para ello )

  5. Actualmente, esta característica está ligeramente documentada

CommonsWare
fuente
@CommonsWare si no está disponible un largeHeap, ¿cómo puedo eliminar objetos cargados previamente (como imágenes)?
Jeongbebs
@MiguelRivera: Para las imágenes, idealmente reciclas su memoria (ver más inBitmapadelante BitmapOptions). Más allá de eso, elimine todas las referencias a ellos, y eventualmente se recolectarán basura.
CommonsWare
¿Y qué decisión sugieres?
Gennadiy Ryabkin
@zest: No sé a qué te refieres, lo siento.
CommonsWare
2
@Eftekhari: no directamente, para su aplicación. Tener más cosas puede hacer que pases más tiempo de CPU revisando esas cosas, pero los detalles allí dependerán de lo que estés haciendo con la memoria y no está directamente relacionado con haberlo solicitado android:largeHeap. Sin embargo, solicitar un gran montón puede dañar la experiencia del usuario en general, al obligar a otros procesos de aplicación a finalizar antes de lo que se hubiera necesitado de lo contrario.
CommonsWare
22

no puede aumentar el tamaño del montón dinámicamente.

puedes solicitar usar más usando android:largeHeap="true"el manifiesto.

también, puede usar native memory (NDK & JNI), por lo que realmente omite la limitación del tamaño de almacenamiento dinámico.

Aquí hay algunas publicaciones que he hecho al respecto:

y aquí hay una biblioteca que hice para ello:

desarrollador de Android
fuente
@ por aplicación, ¿el límite de almacenamiento dinámico a nivel de Java y nativo es diferente? es decir, en s5 devcie 128mb java heap limit y nativo puede tomar otro128 mb?
NitZRobotKoder
El tamaño del almacenamiento dinámico es constante para cada aplicación (el tamaño depende del hardware y la ROM) y debe ser el mismo para todos. La memoria nativa es la real del dispositivo, pero por supuesto también está limitada, ya que parte del sistema operativo la utiliza.
Desarrollador de Android
quise decir si mi aplicación está usando say .so + java android Platform + java POJO logic + JavaScript. ¿Android tiene un tamaño de almacenamiento dinámico diferente en cada nivel?
NitZRobotKoder
@NitZRobotKoder No. El tamaño del almacenamiento dinámico es para el mundo Java / Kotlin, donde puede obtener la excepción OOM si usa demasiado. Por lo demás, es la memoria nativa.
Desarrollador de Android
6

Use el segundo proceso. Declarar en AndroidManifestnuevo Servicecon

android:process=":second"

Intercambio entre primer y segundo proceso sobre BroadcastReceiver

Yura Shinkarev
fuente
5

Esto se puede hacer de dos maneras según su sistema operativo Android.

  1. Puede usar la android:largeHeap="true"etiqueta de aplicación del manifiesto de Android para solicitar un tamaño de almacenamiento dinámico mayor, pero esto no funcionará en ningún dispositivo anterior a Honeycomb.
  2. En los dispositivos anteriores a 2.3, puede usar la clase VMRuntime , pero esto no funcionará en Gingerbread y superior. Vea a continuación cómo hacerlo.
VMRuntime.getRuntime().setMinimumHeapSize(BIGGER_SIZE);

Antes de configurar HeapSize, asegúrese de haber ingresado el tamaño apropiado que no afectará la funcionalidad de otras aplicaciones o sistemas operativos. Antes de la configuración, solo verifique cuánto tamaño toma su aplicación y luego configure el tamaño solo para cumplir con su trabajo. No use tanta memoria, de lo contrario, otras aplicaciones podrían afectar.

Referencia: http://dwij.co.in/increase-heap-size-of-android-application

Desarrollador web en Pune
fuente
44
Entonces, aparentemente, <2.3 tiene un camino, y> 2.3 tiene un camino, ¡pero 2.3 está jodido!
Michael
3

Por lo que recuerdo, podría usar la VMRuntimeclase en las primeras versiones de Android, pero ahora ya no puede.

Sin embargo, no creo que permitir que el desarrollador elija el tamaño de almacenamiento dinámico en un entorno móvil pueda considerarse tan seguro. Creo que es más fácil que pueda encontrar una manera de modificar el tamaño del almacenamiento dinámico en un dispositivo específico (no en el lado de la programación) que al intentar modificarlo desde la propia aplicación.

Jack
fuente
0

El aumento de Java Heap consume injustamente los recursos móviles con déficit. A veces es suficiente esperar al recolector de basura y luego reanudar sus operaciones después de reducir el espacio de almacenamiento dinámico. Use este método estático entonces.

Zon
fuente