Java — Runtime.freeMemory()

#java

#java

Вопрос:

Я пытался увидеть использование Runtime.freeMemory().

В документации говорится, что это «Возвращает объем свободной памяти в виртуальной машине Java»

Я выполнил простую программу для проверки этого. Программа ниже:

 public class Test {

 public static void main(String a[]) throws Exception {
    System.out.println("Total memory: "  Runtime.getRuntime().totalMemory());
    System.out.println("Free memory: "  Runtime.getRuntime().freeMemory());
    Integer intArr[]= new Integer[10000];
    for(int i =0; i<10000;i  ){
        intArr[i] = new Integer(i 500);
    }
    System.out.println("Free memory: "  Runtime.getRuntime().freeMemory());
    System.out.println("sample print :"  intArr[0]);
    System.out.println("sample print :"  intArr[5000]);
    System.out.println("sample print :"  intArr[9999]);
 }  
}
  

Вывод:

Общий объем памяти: 67108864

Свободная память: 61822408 < До выделения 10000 объектов>

Свободная память: 61822408 < Размер остается неизменным даже после выделения 10000 объектов. почему?>

пример печати: 500

пример печати: 5500

пример печати: 10499

Поскольку объекты создаются в куче, значение «Свободная память», напечатанное во второй раз, должно быть меньше первого вывода, верно?

Но он выводит то же значение. Кто-нибудь может, пожалуйста, объяснить, почему он выводит одно и то же значение?

Комментарии:

1. Вы должны попробовать что-то НАМНОГО большее, чем 10000 целых объектов, чтобы увидеть разницу.

2. @CoolBeans — зависит от платформы и JVM. Выполнение приведенного выше кода на моем компьютере (Linux Sun JVM 1.6_22) показывает уменьшение объема свободной памяти.

3. какую ОС вы используете и какую версию Java? Ваш код работает так, как ожидалось, на моей машине.

4. @Brain — ОС: Windows XP, JDK -1.6.0_05. Спасибо за ответ!

Ответ №1:

Я знаю, что это не тот ответ, который вы хотели, но согласно JavaDoc — freeMemory возвращает:

приближение к общему объему памяти, доступному в настоящее время для будущих выделенных объектов, измеряемое в байтах.

Просто чтобы проверить это — я взял ваш код и запустил дважды. Один раз с размером массива, равным 10000, и один раз со 100. Я также добавил другую печать сразу после:

 Integer intArr[]= new Integer[10000];
  

При запуске с 10,000 — я получил ожидаемый результат, уменьшение 40,0016 bytes объема свободной памяти сразу после создания экземпляра массива.

При запуске с 100 я получил точно такой же объем свободной памяти до и после создания экземпляра массива — не желаемый эффект.

Как уже указывалось в большинстве ответов — поскольку это собственный метод — зависит от JVM и, следовательно, может действовать по-разному на любой платформе. Я продолжаю работать Windows 7 с Eclipse built-in JVM (v3.6) .

Но я думаю, что ключевое слово здесь — приближение.

Ответ №2:

Память выделяется из окружающей операционной системы большими порциями. Объединенные 10000 объектов недостаточно велики, чтобы вызвать дополнительное выделение.

Комментарии:

1. Это не должно быть фактом, поскольку freeMemory должно быть связано с памятью, которая внутренне управляется самой JVM, ты не уверен в этом..

2. зависит от платформы и JVM. Запуск кода операционной системы на моем компьютере (Linux Sun JVM 1.6_22) показывает уменьшение объема свободной памяти

Ответ №3:

Только что проверил байт-код .. фрагмент следующий, и он находится посередине двух printf :

 SIPUSH 10000
ANEWARRAY java/lang/Integer
ASTORE 1
  

Таким образом, он действительно распределяет массив динамически и freeMemory должен возвращать другое значение. Поскольку он этого не делает, я предполагаю, что это действительно зависит от платформы / версии, как уже указывалось.

Например, на моей машине это действительно меняется:

 Free memory: 81915960
Free memory: 81353824
  

Просто еще одно предположение: возможно, это зависит от начального параметра размера кучи JVM, так что, если JVM запускается с достаточным количеством кучи, уже готовой к использованию, ей не нужно выделять ее до определенного порога (это -Xms настройка, вы могли бы попробовать увеличить или уменьшить ее, чтобы увидеть, изменится ли что-то).

Комментарии:

1. Вы можете сэкономить эти усилия — это неправда.