Estoy tratando de determinar cuánta memoria de pila consume cada método cuando se ejecuta. Para hacer la tarea, he ideado este sencillo programa que se acaba de forzar un StackOverflowError
,Inferir el uso de la memoria de pila de un método en Java
public class Main {
private static int i = 0;
public static void main(String[] args) {
try {
m();
} catch (StackOverflowError e) {
System.err.println(i);
}
}
private static void m() {
++i;
m();
}
}
imprimir un entero decirme cuántas veces m()
se llamaba. Me he fijado manualmente tamaño de la pila de la JVM (-Xss
parámetro VM) a valores variables (128k, 256k, 384 K), obteniendo los siguientes valores:
stack i delta
128 1102
256 2723 1621
384 4367 1644
delta se calculó por mí, y es el valor entre el último línea i y la actual. Como se esperaba, es fijo. Y ahí radica el problema. Como sé que el incremento de la memoria del tamaño de la pila fue de 128k, eso produce algo así como un uso de memoria de 80 bytes por llamada (lo que parece exagerado).
Mirando hacia arriba m()
en BytecodeViewer de, obtenemos profundidad máxima de una pila de 2. Sabemos que este es un método estático y que no hay this
paso de parámetros, y que m()
tiene argumentos. También debemos tener en cuenta el puntero de la dirección de retorno. Entonces debería haber algo así como 3 * 8 = 24 bytes usados por llamada a método (supongo que 8 bytes por variable, que por supuesto puede estar totalmente apagado. ¿Lo es?). Incluso si es un poco más que eso, digamos 48bytes, todavía estamos lejos del valor de 80bytes.
Pensé que podría tener algo que ver con la alineación de memoria, pero la verdad es que en ese caso tendríamos un valor de aproximadamente 64 o 128 bytes, diría yo.
Estoy ejecutando una JVM de 64 bits en un sistema operativo Windows 7 de 64 bits.
He hecho varias suposiciones, algunas de las cuales pueden ser totalmente inactivas. Siendo ese el caso, soy todo oídos.
Antes de que alguien comienza a preguntar por qué estoy haciendo esto I must be frank..
Esa fue una información perspicaz, señor. Sin embargo, ¿podría teorizar sobre por qué cada llamada al método parece tener 80 bytes? –
¿Puedo decirle qué información tiene mi propia implementación JVM dentro de la estructura Frame? – Jivings
@devouredelysium Actualicé mi respuesta con la fuente OpenJDK. – Jivings