Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Как узнать, сколько памяти использует программа

Короткий ответ

Занятая память кучи — это 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() — Немедленно завершает программу с заданным кодом выхода.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.