Я пытаюсь определить, сколько памяти стека потребляет каждый метод при запуске. Чтобы выполнить эту задачу, я разработал эту простую программу, которая просто заставит StackOverflowError
,
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();
}
}
печать целого числа, указывающего, сколько раз было вызвано m()
. Я вручную установил размер стека JVM (-Xss
параметр VM) на различные значения (128k, 256k, 384k), получив следующие значения:
stack i delta
128 1102
256 2723 1621
384 4367 1644
delta была рассчитана мной, и это значение между последней строкой я и текущей. Как и ожидалось, он исправлен. И есть проблема. Поскольку я знаю, что размер памяти размера стека был на 128 тыс., Что дает примерно 80 байтов использования памяти за вызов (что кажется преувеличенным).
Поднимая m()
в BytecodeViewer, мы получаем максимальную глубину стека 2. Мы знаем, что это статический метод и что нет параметра this
, и что m()
не имеет аргументов. Мы также должны учитывать указатель обратного адреса. Таким образом, должно быть что-то вроде 3 * 8 = 24 байта, используемого для вызова метода (я принимаю 8 байтов на переменную, что, конечно, может быть полностью отключено.)? Даже если это немного больше, скажем 48 байтов, мы все еще далеки от значения 80 байтов.
Я думал, что это может быть связано с выравниванием памяти, но правда в том, что в этом случае мы бы имели значение примерно 64 или 128 байт, я бы сказал.
Я запускаю 64-битную JVM под 64-разрядной ОС Windows7.
Я сделал несколько предположений, некоторые из которых могут быть полностью отключены. В этом случае я все уши.
Прежде чем кто-нибудь начнет спрашивать, почему я делаю это Я должен быть откровенным..