2016-04-20 3 views
6

Я работаю с некоторыми алгоритмами моделирования в R, один из которых работает на Java (bartMachine). Я обнаружил, что с размером моих данных мне нужно увеличить максимальное пространство кучи для java перед запуском алгоритма моделирования.Должен ли я сбросить максимальное пространство кучи Java после использования?

Я делаю это так:

options(java.parameters = "-Xmx16g")

Мой вопрос, нужно ли мне сбросить пространство кучи после этого, если нет другого алгоритма не собирается использовать Java (или, по крайней мере, это много кучи пространства)? Или память, выделенная java, будет исправлена ​​по мере необходимости без потери производительности?

Я уже искал некоторые предметы по этому вопросу, и я понимаю как изменить или опустить кучу пространства. Я также понимаю, что R/Java сделает сборку мусора, чтобы удалить старые объекты из памяти, чтобы освободить больше места.

Что я не понимаю, так это то, как изменение пространства кучи влияет на память, доступную для других программ, и необходимо ли это или даже хорошая идея в этом случае изменить размер кучи после использования.

Некоторые из ответов/ресурсов Я уже смотрел на:

Is there a way to lower Java heap when not in use?

Java garbage collector - When does it collect?

http://www.bramschoenmakers.nl/en/node/726

https://cran.r-project.org/web/packages/bartMachine/bartMachine.pdf

ответ

5

Это определяется реализацией и в зависимости от реализации осуществляется довольно много параметров. The garbage collector can affect it. На Mac с использованием Oracles JVM 1.7 по умолчанию используется параллельный коллектор -XX:+UseParallelGC, и этот сборщик не освобождает память обратно в ОС. Я попробовал это на mac, и он ничего не высвободил, но использовал -XX:+UseG1GC. Вы можете увидеть, что версия по умолчанию для вас с помощью этого:

java -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -version 

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

-XX:MinHeapFreeRatio (default is 40) 
-XX:MaxHeapFreeRatio (default is 70) 

, но они как попало (виртуальная машина решает, когда он освобождает память, только освободив массу объектов может не вызвать его).

5

Проработав с не-ML-программой, которая в настоящее время является Java-тяжелой, я чувствую вашу боль.

Я не могу сказать, нужно ли перезаписывать динамически выделенную память на основе одного неоспоримого технического факта, но мой личный опыт подсказывает мне, что если вы собираетесь продолжать обработку в среде native R после работы с Java, вы вероятно, должен. Лучше всего контролировать то, что вы можете.

Вот почему:

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

Это даже происходит просто чтение и запись больших файлов excel через XLConnect, который управляется Java; память быстро застревает. Кажется, что неудача в том, как R и Java играют друг с другом.

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

Также R только видит объекты в памяти, которые он создает, а не те, которые он интерпретирует, поэтому ваш куб из Java будет задерживаться без ведома R. Так что если JVM создал его, R не будет его очищать, если Java не делает этого прежде чем идти в бездействии. И если память выборочно переработана, вы можете иметь фрагментированные промежутки памяти, которые сильно влияют на производительность.

Мой личный подход заключался в создании наборов, переменных, фреймов ... подмножество только для того, что мне нужно, затем rm() и gc() ... удалить и принудительно собрать мусор.

Перейдите на следующий шаг и делайте тяжелый подъем. Если я запустил пакет на основе Java, я сделаю эту очистку чаще, чтобы сохранить память чистой.

Как только процесс Java завершен, я использую detach(yourlibraryname) и gc(), чтобы очистить все.

Если вы скорректировали «кучи», я бы добавил, что изменил настройку, уменьшив выделение, которое вы даете динамической памяти Javas, поскольку R не может вернуть ее, если виртуальная машина Java все еще задействована, но не работает насколько я смог убедиться. Поэтому вы должны сбросить его и вернуть R, что использовать R. Я думаю, что в долгосрочной перспективе это принесет пользу вам с более быстрой обработкой и меньшими блокировками.

Лучший способ узнать, как это влияет на вашу систему, как вы используете это использовать sys.time или proc.time функцию, чтобы увидеть, как долго ваш скрипт берет с и без принудительной сборки мусора, удаления, отрядах и кучного перераспределении.

Вы можете получить твердое понимание о том, как сделать это здесь:

IDRE -UCLE proc.time functions

Надеется, что это помогает некоторым!

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