Ответ 1
Общая память, доступная JVM, составляет около 2-4 ГБ для 32-битной JVM и квадрат для 64-битной JVM (около 4-16EB). JVM разбивает память на:
-
Память кучи (распределение управляется с помощью параметров JVM -Xms и -Xmx)
- построенные экземпляры объектов и массивов
- статические классы и данные массива (включая экземпляры объектов/массивов)
- экземпляры потоков (экземпляры объектов, данные времени выполнения и метаданные, включая ссылки на блокировку монитора потока)
-
Память без памяти
- совокупная память стека
- в потоковой памяти стека (распределение по потокам, управляемое с помощью опции JVM -Xss): кадры метода, аргументы, возвращаемые значения, локально объявленные примитивы и ссылки на объекты
- статические константы (примитивы)
- Пул экземпляров String
- код java: загруженные классы и метаданные
- Внутренняя память JVM (код JVM и структуры данных)
- совокупная память стека
См. http://docs.oracle.com/javase/7/docs/api/java/lang/management/MemoryMXBean.html и http://www.yourkit.com/docs/kb/sizes.jsp
Есть ли какой-либо метод, по которому мы можем вычислить размер стека вызовов метода динамически в нашей программе
- В Java SE/Java EE нет стандартного метода для получения фактического использования памяти потокового потока.
- Существуют стандартные методы для получения совокупной памяти без кучи: MemoryMxBean.getNonHeapMemoryUsage(). Ссылаясь на это, вы не можете принимать динамические решения в коде, чтобы избежать исключения
StackOverflow
- Существуют стандартные методы для получения стека вызовов без использования памяти: Thread.getStackTrace() ThreadMxBean.getThreadInfo() и ThreadInfo.getStackTrace()
Я рекомендую вам не делать то, что вы предлагаете в вопросе, потому что:
- Вы не можете сделать это без какого-либо сложного JVM-специфического API, который использует инструменты/интроспекты для использования динамической памяти стека потоков - где вы найдете такой API?
- В потоке с потоком обычно потребляется крошечный объем памяти по сравнению со всей JVM, поэтому обычно легко назначить достаточно, чтобы соответствовать вашему алгоритму (например, по умолчанию размер стека размером 128 КБ для Windows 64bit JVM, в то время как 2 ГБ памяти может быть заложена в бюджете для всей JVM)
- Это было бы очень ограничено по мощности: если ваша логика действительно требовала вызова метода, но вы не могли из-за недостаточной памяти, тогда ваша программа была бы сломана в этот момент. Исключение
StackOverflow
на самом деле будет лучшим ответом. -
То, что вы пытаетесь сделать, может быть anti-design anti-pattern.
"Правильный" подход заключался бы в определении требований к программе, определении требуемой среды выполнения (включая минимальную/необходимую память!) И разработке вашей программы соответственно для оптимальной производительности и использования памяти.Анти-шаблон - это не думать об этих вещах надлежащим образом во время проектирования и разработки, и просто представьте себе, что магия интроспекции времени выполнения может охватывать это. Могут существовать некоторые (редкие!) Приложения с высокой производительностью, требующие радикальной перестройки алгоритма во время выполнения, чтобы точно соответствовать обнаруженным ресурсам - но это сложно, уродливо и дорого.
И даже тогда, вероятно, лучше было бы изменить динамические изменения динамического алгоритма на макроуровне от параметра -Xss, а не на микроуровне от точного потребления памяти стека в месте в коде.