#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. Вы можете сэкономить эти усилия — это неправда.