2012-08-12 4 views
6

Предположим, что у меня есть приложение Swings Java, Я установил минимальную кучу 64 МБ и максимальную кучу 2 ГБ, , когда пользователь запустит приложение, появится экран регистрации , в настоящее время приложение использует 64 МБ, права? Из моей Windows 7 я вижу, что приложение Java выделено 64MB из монитора ресурсов памяти ОС (на самом деле это больше, чем 64 МБ, потому что для работы JVM требуется некоторая память для его задачи).Освободить Java-память для ОС во время выполнения.

После этого пользователь выполняет очень тяжелую работу, тогда приложение использует 2G. После этого пользователь выйдет из приложения, экран регистрации снова отобразится (приложение еще не закрыто). В это время реальная память, что приложение использует 64 МБ (предположим, что это идеальное приложение для управления памятью), , но с ОС это приложение все еще использует 2G ОЗУ, я могу видеть его на мониторе ресурсов ОС.

Я хочу, чтобы мое приложение освобождало память для ОС, когда ей не нужно использовать большую память. Могу ли я сделать это во время выполнения с помощью java-приложения?

Я имею в виду, когда мое приложение нужно использовать 64Мб ОЗУ, то ОС дает ему 64Мб только когда это нужно 2 Гб оперативной памяти, то ОС дает ему 2 ГБ, после этого ему потребуется 64 Мб оперативной памяти, то ОС дает ему 64MB только снова, Я не хочу, чтобы он тратил 2000MB - 64MB = 1936MB.

Могу ли я это сделать?

Спасибо,

+1

Проверьте этот вопрос: http://stackoverflow.com/q/1481178/562906 – sinelaw

ответ

1

Вы можете распоряжаться объектами и предложить сборщик мусора делать свою работу, но если GC не чувствую, что это необходимо, то запрос будет проигнорирован. Итак, в резюме, «нет».

Обратите внимание, что память назначена Java-приложениям. перед приложением. запускается и не регулируется.

5

Я хочу, чтобы мое приложение освобождало память ОС, когда ей не нужно использовать большую память. Могу ли я сделать это во время выполнения с помощью java-приложения?

Нет, вы не можете.

В некоторых случаях GC выдает память обратно в ОС по своему усмотрению, но я не знаю о какой-либо JVM, которая позволяет приложению сообщать GC об этом. И, кроме того, GC довольно консервативен в этом, потому что ... как общее правило ... JVM будет работать более эффективно с большим объемом памяти, а постоянный запрос/предоставление памяти для ОС неэффективен.


Обратите внимание, что параметр настройки ГХ -XX:MaxHeapFreeRatio может быть использован для указания максимального соотношения свободно использоваться кучей перед GC даст память назад. Однако есть осложнения. Например, не все доступные GC уважают эту опцию. Если вы собираетесь попробовать этот подход, я предлагаю вам провести некоторое исследование ... и не ожидайте чудес.

+1

Это вопрос GC? Я так не думаю. GC очищает объекты и освобождает кучу, но утилизация кучи - это что-то еще. –

+0

@AmirPashazadeh - вам нужно будет прочитать исходный код JVM, чтобы узнать, где на самом деле код, который возвращает память. –

+1

Обратите внимание, что эти настройки учитываются только при использовании singeThreadGC. Я нашел это в этом ответе http://stackoverflow.com/a/8170123/775513 после того, как вы не заметили никаких изменений поведения при использовании этой опции. – cproinger

2

Серийный коммутатор в горячей точке даст память обратно ... по крайней мере, она привыкла. Ваше представление будет погружаться в нос.

Все сборщики мусора в IBM J9 jvm освободят память. Я не уверен, что этот jvm является бесплатной загрузкой ...

Лучший ответ: почему вы обеспокоены? В наши дни память грязная, а свободная память - впустую. Действительно ли это проблема? В любом случае ОС будет загружать лишнюю неиспользуемую память на диск. Лучший ответ - игнорировать его. :)

Возможно, вы также захотите хранить хранилище в Google, возможно, Teracotta/eh cache.

EDIT:

Я только что заметил в JDK1.7u6, что использование G1GC с небольшим XMS и большой Xmx, сборщик мусора будет уменьшить размер кучи после нескольких сборок мусора, где были освобождены лишние объекты ,

+1

Потому что моему клиенту это не понравилось. В 99% случаев они выполняли работу, которая потребляет около 300 - 400 МБ ОЗУ. Есть 1% случаев, когда они выполняли тяжелую работу, тогда приложение использует 2 ГБ ОЗУ. И они сказали, что мое приложение использует слишком много памяти, когда это не нужно делать. Им нужна память для других приложений. Кажется, что всякий раз, когда приложение java работает в максимальной памяти, он не будет возвращать память ОС, когда она работает в минимальной памяти. Правильно ли это? – user1592936

+1

см. Обновление, я обнаружил новую информацию ... :) Извините, что ваш клиент настолько придирчив, их не должно быть. Они должны полагаться на свою операционную систему, чтобы правильно управлять памятью. –

+0

Ну, небезосновательно спросить, что Java правильно обрабатывает память (и я говорю это как разработчик Java). Я не согласен в общем, что удерживание в 5-10 раз памяти, требуемой в настоящее время неограниченно или даже в течение длительного периода, является правильным поведением, если на машине больше ничего не работает. – nsandersen

5

Я опубликовал результаты своих испытаний over there. В принципе, MaxHeapFreeRatio не соблюдается в каждой реализации GC, и, чтобы ухудшить ситуацию, кажется необходимым, чтобы было достаточно активности кучи, чтобы своевременно инициировать ее, т.е. может быть, что вам требуется 2 полных GC-прогона, чтобы фактически освободить память для ОС. И если у вас есть объем памяти с памятью X GB, то вам, вероятно, придется выделить 1 или 2 раза этой суммы, чтобы вызвать сокращение кучи. Или вы вызываете System.gc() вручную.

Если производительность не является проблемой, и объем памяти все, что имеет значение, попробуйте:

-XX:UseSerialGC -Xms16M -Xminf=5 -Xmaxf=10 
+0

Интересный блог. Хорошая работа. Однако я хотел бы знать, как долго вы ждали. Пример. Каким будет потребление памяти JVM (как видно из ОС) после того, как вы сделали свои петли и обручи, а затем простаивали, скажем, 1 час? По «простоя» я имею в виду отсутствие активности выделения памяти. – peterh

+0

AFAIK GC вызван изменениями памяти ... так что просто ждать ничего не получится. Попробуйте сами, код есть. – user1050755

+0

Интересное сообщение. Кстати, для Oracle и IBM VM значения для 'Xminf' и' Xmaxf' должны быть процентами (от 0.0 до 1.0) и без ведущего '='. См. [Здесь] (https://docs.oracle.com/cd/E19683-01/806-7930/filestructure-8/index.html), [здесь] (http://www-01.ibm.com/ support/knowledgecenter/SSYKE2_7.0.0/com.ibm.java.lnx.70.doc/diag/appendixes/cmdline/xmaxf.html) и [здесь] (http://bugs.java.com/bugdatabase/view_bug. делать? bug_id = 8025661). – xav

0

Попробуйте разветвление части вашего кода в отдельный поток и утилизировать его, если вам не нужно больше.

+0

Это мало смысла в контексте Java. (И если вы имеете в виду потоки Java, то это не приведет к тому, что пытается сделать OP - убедить JVM вернуть память кучи обратно в ОС.) –

Смежные вопросы