Я пытаюсь определить, сколько памяти стека потребляет каждый метод при запуске. Для выполнения этой задачи я разработал эту простую программу, которая просто заставит 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
дельта была рассчитана мной, и это значение между последней строкой i и текущей. Как и ожидалось, это исправлено. И в этом проблема. Насколько я знаю, приращение памяти размера стека было на 128 КБ, что дает что-то вроде использования памяти 80 байт на вызов (что кажется преувеличенным).
Глядя на m ()
в BytecodeViewer, мы получаем максимальную глубину стека 2. Мы знаем, что это статический метод и что здесь нет передачи этого
параметра и того m ()
не имеет аргументов. Мы также должны учитывать указатель адреса возврата. Таким образом, должно быть что-то вроде 3 * 8 = 24 байта, используемых для каждого вызова метода (я предполагаю, что 8 байтов на переменную, что, конечно, может быть полностью отключено. Не так ли?). Даже если это немного больше, скажем 48 байтов, мы все еще далеки от значения 80 байтов.
Я думал, что это может иметь какое-то отношение к выравниванию памяти, но правда в том, что в этом случае у нас будет значение примерно 64 или 128 байтов, я бы сказал.
Я использую 64-битную JVM под 64-битной ОС Windows7.
Я сделал несколько предположений, некоторые из которых могут быть совершенно неверными. В таком случае я весь на слуху.
Прежде чем кто-нибудь начнет спрашивать, зачем я это делаю , я должен быть откровенен ..