Сборщик мусора в MATLAB? - PullRequest
       61

Сборщик мусора в MATLAB?

28 голосов
/ 18 сентября 2009

Какая у вас ментальная модель? Как это реализовано? Какие у него сильные и слабые стороны? MATLAB GC против Python GC ?

Иногда я вижу странные узкие места в производительности при использовании вложенных функций MATLAB в коде, который в противном случае выглядит безобидно, я уверен, что это из-за GC. Сборщик мусора является важной частью VM, и Mathworks не делает его публичным.

Мой вопрос касается собственной кучи MATLAB и GC! Не об обработке объектов Java / COM / предотвращении ошибок «нехватки памяти» / распределении переменных стека.

РЕДАКТИРОВАТЬ: первый ответ на самом деле является мета-ответ "Почему я должен заботиться?". Меня это волнует, потому что GC проявляется при реализации шаблона связанный список или MVC .

Ответы [ 3 ]

44 голосов
/ 29 сентября 2009

Это список фактов, которые я собрал. Вместо ГХ термин выделение памяти (де) представляется более подходящим в этом контексте.

Мой основной источник информации - блог Лорен (особенно его комментарии) и эта статья из MATLAB Digest.

Из-за своей ориентации на численные вычисления с возможными большими наборами данных MATLAB действительно хорошо справляется с оптимизацией стековых объектов производительности, например, используя операции на месте с данными и вызов по ссылке для аргументов функции. Кроме того, благодаря своей ориентации модель памяти принципиально отличается от таких ОО-языков, как Java.

У MATLAB официально не было пользовательской кучи памяти до версии 7 (в версии 6 была недокументированная функциональность reference в файлах schema.m). MATLAB 7 имеет кучу как в виде вложенных функций (замыканий), так и для обработки объектов , их реализация разделяет одни и те же основы. Как примечание стороны, OO может быть эмулированным с замыканиями в MATLAB (интересно до 2008a).

Удивительно, но можно изучить всю рабочую область включающей функции, захваченную дескриптором функции (замыкание), см. Функцию functions (fhandle) в справке MATLAB. Это означает, что рабочая область заморожена в памяти. Вот почему cellfun/arrayfun иногда очень медленный при использовании внутри вложенных функций.

Есть также интересные сообщения Лорен и Брэда Фелана об очистке объекта.

Самым интересным фактом об освобождении кучи в MATLAB является, на мой взгляд, то, что MATLAB пытается делать это каждый раз, когда происходит освобождение стека, т.е. при выходе из каждой функции. Это имеет преимуществ , но также является огромным штрафом процессора, если освобождение кучи происходит медленно. И на самом деле это очень медленно в MATLAB в некоторых сценариях!

Проблемы производительности освобождения памяти MATLAB, которые могут ударить по коду, довольно серьезны. Я всегда замечаю, что непреднамеренно представляю циклические ссылки в своем коде, когда он неожиданно работает в 20 раз медленнее и иногда требуется несколько секунд между выходом из функции и возвратом к вызывающей стороне (время, потраченное на очистку). Это известная проблема, см. Дейв Фоти и в этом старом посте на форуме , код которого используется для визуализации производительности этой картины (тесты проводятся на разных машинах, поэтому сравнение абсолютных временных интервалов для разных MATLAB версии не имеет смысла):

Линейное увеличение размера пула для объектов-ссылок означает полиномиальное (или экспоненциальное) снижение производительности MATLAB! Для объектов-значений производительность, как и ожидалось, линейна.

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

EDIT : я всегда сталкивался с проблемой производительности с множеством небольших вложенных функций, но недавно я заметил, что по крайней мере с 2006a очистка одиночной вложенной области действия с некоторые мегабайты данных также ужасны, требуется всего 1,5 секунды, чтобы установить пустую переменную вложенной области видимости!

РЕДАКТИРОВАТЬ 2 : наконец я получил ответ - от самого Дэйва Фоти . Он признает недостатки, но говорит, что MATLAB собирается сохранить свой нынешний подход к детерминированной очистке.

Легенда: чем меньше время выполнения, тем лучше

R2006a R2008a R2009a

13 голосов
/ 19 сентября 2009

MATLAB делает рабочее пространство очень понятным в браузере рабочего пространства или с помощью команды "whos". Это показывает вам все объекты, созданные вашими командами и сколько памяти они занимают.

feature('memstats')

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

JVM обрабатывает сборку мусора только для элементов Java. Поэтому, если вы откроете файл в редакторе и закроете его, Java позаботится об удалении окна, текста и т. Д. Из памяти. Если вы создаете Java-объект в рабочем пространстве MATLAB, его сначала нужно очистить, а затем он может быть очищен с помощью jvm.

В нашем техническом комментарии много информации об управлении памятью программы: http://www.mathworks.com/support/tech-notes/1100/1106.html

И я недавно написал об обработке памяти Java в блоге MATLAB Desktop: http://blogs.mathworks.com/desktop/2009/08/17/calling-java-from-matlab-memory-issues/

Если вас интересует, что происходит с памятью, выделяемой при выходе из функции или при изменении размера переменной ... Я почти уверен, что это коммерческая тайна, и она меняется при каждом выпуске. Вы никогда не должны это замечать, и если у вас возникают проблемы с производительностью, которые, как вы подозреваете, связаны с объектом managmenet, отправьте заявку в службу технической поддержки: http://www.mathworks.com/support

2 голосов
/ 21 сентября 2009

Похоже, вы пытаетесь создать какой-то аргумент Python против MATLAB. Меня не интересует этот аргумент.

Мета-ответ на ваш мета-вопрос.

На самом деле очень важно, чтобы тебе было все равно. Когда я говорю это, я не хочу ограничивать это управлением памятью MATLAB. Это распространяется на Python, Java, .NET и любой другой язык, который выполняет динамическое распределение памяти и все еще находится в активной разработке.

Чем больше вы знаете о текущем механизме управления памятью, тем больше вероятность, что вы защитите код от этой конкретной реализации, тем выше вероятность того, что вы не выиграете от будущих улучшений производительности. Ряд хороших примеров этого можно найти в gc Java, написанном Брайаном Гетцем на developerworks.com:

.

http://www.ibm.com/developerworks/library/j-jtp01274.html

Вы можете сказать, что это важно знать. Я против, что все дело в требованиях. Более уместный вопрос: соответствуют ли языки, которые я рассматриваю для своего проекта, моим потребностям с точки зрения производительности, усилий по разработке, удобства обслуживания, переносимости, опыта моих разработчиков и т. Д., И т. Д.

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

...