pilas - ¿Se almacena una matriz Java de primitivas en pila o en montón?
pilas con stack en java (5)
Tengo una declaración de matriz como esta:
int a[];
Aquí a
es una matriz de tipo int
primitivo. ¿Dónde está almacenada esta matriz? ¿Está almacenado en montón o pila? Este es un tipo primitve int
, todos los tipos primitivos no se almacenan en heap.
Como dijo Gurukulki, está almacenado en el montón. Sin embargo, su publicación sugirió un malentendido probablemente debido a una persona bien intencionada que propaga el mito de que "los primitivos siempre viven en la pila". Esto no es cierto. Las variables locales tienen sus valores en la pila, pero no todas las variables primitivas son locales ...
Por ejemplo, considera esto:
public class Foo
{
int value;
}
...
public void someOtherMethod()
{
Foo f = new Foo();
...
}
Ahora, ¿ f.value
vive f.value
? El mito sugeriría que está en la pila, pero en realidad es parte del nuevo objeto Foo
y vive en el montón 1 . (Tenga en cuenta que el valor de f
sí es una referencia, y vive en la pila).
A partir de ahí, es un paso fácil para las matrices. Puedes pensar que una matriz es solo un montón de variables, por lo que new int[3]
es un poco como tener una clase de esta forma:
public class ArrayInt3
{
public readonly int length = 3;
public int value0;
public int value1;
public int value2;
}
1 De hecho, es más complicado que esto. La distinción pila / montón es principalmente un detalle de implementación. Creo que algunas JVM, posiblemente experimentales, pueden decir cuándo un objeto nunca "escapa" de un método, y pueden asignar el objeto completo en la pila. Sin embargo, conceptualmente está en el montón, si eliges cuidar.
En el lenguaje de programación Java, las matrices son objetos, se crean dinámicamente y se pueden asignar a variables de tipo Object.
http://java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html
Es una matriz de tipos primitivos que en sí misma no es primitiva. Una buena regla empírica es cuando la nueva palabra clave está involucrada, el resultado estará en el montón.
Se almacenará en el montón
porque array es un objeto en java.
EDITAR : si tienes
int [] testScores;
testScores = new int[4];
Piense en este código como diciendo al compilador: "Cree un objeto de matriz que contendrá cuatro entradas y testScores
a la variable de referencia llamada testScores
. Además, continúe y configure cada elemento int
en cero. Gracias".
Solo quería compartir algunas pruebas que realicé sobre este tema.
Matriz de tamaño 10 millones
public static void main(String[] args) {
memInfo();
double a[] = new double[10000000];
memInfo();
}
Salida:
------------------------
max mem = 130.0 MB
total mem = 85.0 MB
free mem = 83.6 MB
used mem = 1.4 MB
------------------------
------------------------
max mem = 130.0 MB
total mem = 130.0 MB
free mem = 48.9 MB
used mem = 81.1 MB
------------------------
Como ve, el tamaño del montón usado se incrementa en ~ 80 MB, que es 10 m * sizeof (doble).
Pero si tenemos uso doble en lugar de doble
public static void main(String[] args) {
memInfo();
Double a[] = new Double[10000000];
memInfo();
}
La salida mostrará 40MB. Solo tenemos referencias dobles, no están inicializadas.
Llenándolo con doble
public static void main(String[] args) {
memInfo();
Double a[] = new Double[10000000];
Double qq = 3.1d;
for (int i = 0; i < a.length; i++) {
a[i] = qq;
}
memInfo();
}
Todavía 40MB. Porque todos apuntan al mismo objeto doble.
Inicializando con doble en su lugar
public static void main(String[] args) {
memInfo();
Double a[] = new Double[10000000];
Double qq = 3.1d;
for (int i = 0; i < a.length; i++) {
a[i] = qq.doubleValue();
}
memInfo();
}
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
Línea
a[i] = qq.doubleValue();
es equivalente a
a[i] = Double.valueOf(qq.doubleValue());
que es equivalente a
a[i] = new Double(qq.doubleValue());
Como creamos nuevos objetos dobles cada vez, volamos el montón. Esto muestra que los valores dentro de la clase doble se almacenan en el montón.