Как узнать, сколько памяти использует программа
Короткий ответ
Занятая память кучи — это totalMemory() - freeMemory() объекта Runtime. Числа зависят от компьютера и меняются от запуска к запуску:
void main() {
Runtime rt = Runtime.getRuntime();
long usedMb = (rt.totalMemory() - rt.freeMemory()) / (1024 * 1024);
IO.println("Used: " + usedMb + " MB");
}Результат:
Used: 42 MBВсе три показателя
maxMemory() — предел кучи, totalMemory() — сколько JVM уже взяла у системы, freeMemory() — свободная часть взятого:
void main() {
Runtime rt = Runtime.getRuntime();
long mb = 1024 * 1024;
IO.println("Max: " + rt.maxMemory() / mb + " MB");
IO.println("Total: " + rt.totalMemory() / mb + " MB");
IO.println("Free: " + rt.freeMemory() / mb + " MB");
}Результат:
Max: 4080 MB
Total: 258 MB
Free: 213 MBСколько памяти заняла операция
Сравните занятую память до и после. Здесь — массив из 10 миллионов чисел long по 8 байт:
long usedMb() {
Runtime rt = Runtime.getRuntime();
return (rt.totalMemory() - rt.freeMemory()) / (1024 * 1024);
}
void main() {
long before = usedMb();
long[] numbers = new long[10_000_000];
long after = usedMb();
IO.println(numbers.length + " numbers");
IO.println("About " + (after - before) + " MB");
}Результат:
10000000 numbers
About 78 MBПредел памяти
Предел кучи задают ключом -Xmx при запуске, например java -Xmx256m Main.java:
void main() {
IO.println(Runtime.getRuntime().maxMemory() / (1024 * 1024) + " MB");
}Результат:
256 MBЧастая ошибка
Считать результат точным. Сборщик мусора освобождает память, когда сам решит, поэтому разность «до» и «после» может включать уже ненужные объекты или, наоборот, оказаться отрицательной. System.gc() перед замером лишь просит JVM собрать мусор. Для точного анализа используют инструменты: VisualVM, JDK Mission Control или jcmd <pid> GC.heap_info.
Функции из этого ответа
- Runtime.getRuntime() — Возвращает объект Runtime текущей JVM: память, число процессоров, обработчики завершения.
- System.nanoTime() — Возвращает показания точного таймера в наносекундах — для замера длительности. Рядом — currentTimeMillis().
- System.exit() — Немедленно завершает программу с заданным кодом выхода.