Как справиться и минимизировать использование памяти в Common Lisp (SBCL) - PullRequest
13 голосов
/ 02 апреля 2009

У меня есть VPS с не очень большим объемом памяти (256 МБ), который я пытаюсь использовать для разработки Common Lisp с SBCL + Hunchentoot для написания простых веб-приложений. Большой объем памяти, по-видимому, используется без каких-либо особых сложностей, и через некоторое время обслуживания страниц он исчерпывает память и либо сходит с ума, используя весь обмен, либо (если обмен не существует) просто умирает.

Так что мне нужна помощь:

  • Узнайте, что использует всю память (если это библиотеки или я, особенно)
  • Ограничить объем памяти, который разрешено использовать SBCL, чтобы избежать большого количества перестановок
  • Работайте аккуратно, когда память заканчивается, а не сбой (поскольку это веб-приложение, я хочу, чтобы оно продолжалось и пыталось очистить).

Полагаю, первые два достаточно просты, но возможен ли третий? Как люди справляются с нехваткой памяти или условиями ограниченной памяти в Лиспе?

(Также отмечу, что 64-битный SBCL, по-видимому, использует буквально вдвое больше памяти, чем 32-битный. Ожидается ли это? Я могу запустить 32-битную версию, если это сэкономит много памяти)

Ответы [ 4 ]

13 голосов
/ 02 апреля 2009

Чтобы ограничить использование памяти SBCL, используйте параметр --dynamic-space-size (например, sbcl --dynamic-space-size 128 ограничит использование памяти до 128M).

Чтобы выяснить, кто использует память, вы можете вызвать (room) (функция, которая сообщает, сколько памяти используется) в разное время: при запуске, после загрузки всех библиотек и затем во время работы (конечно, вызовите (sb-ext:gc :full t) перед комнатой не замерять мусор, который еще не был собран).

Кроме того, можно использовать SBCL Profiler для измерения распределения памяти.

4 голосов
/ 03 апреля 2009

Узнайте, что использует всю память (если это библиотеки или я, особенно)

Аттила Лендвай имеет некоторый специфичный для SBCL код, чтобы выяснить, откуда берутся выделенные объекты. Обратитесь к http://article.gmane.org/gmane.lisp.steel-bank.devel/12903 и напишите ему личное сообщение, если необходимо.

Обязательно попробуйте другую реализацию, желательно с точным GC (например, Clozure CL), чтобы убедиться, что это не специфичная для реализации утечка.

Ограничить объем памяти, который SBCL разрешено использовать, чтобы избежать массивных количество обменов

Уже ответили другие.

Чисто обрабатывать вещи, когда память работает , а не сбой (так как это веб-приложение, которое я хочу, чтобы оно продолжало и попробуйте навести порядок).

256 МБ - это мало, но в любом случае: запланируйте повторяющийся (возможно, 1 с) синхронизированный поток, который проверяет оставшееся свободное пространство. Если свободного места меньше X, используйте exec () для замены текущего образа процесса SBCL новым.

3 голосов
/ 03 апреля 2009

Если у вас нет объявлений типов, я бы ожидал, что 64-битный Lisp займет вдвое больше места, чем 32-битный. Даже простой (маленький) int будет использовать 64-битный кусок памяти. Я не думаю, что оно будет использовать меньше, чем машинное слово, если вы не объявите это.

Я не могу помочь с № 2 и № 3, но если вы поймете № 1, я подозреваю, что это не будет проблемой. Я видел экземпляры SBCL / Hunchentoot, работающие целую вечность. Если я использую огромное количество памяти, это обычно моя вина. : -)

1 голос
/ 02 апреля 2009

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

Типичные вещи, которые держат память дольше ожидаемого, - это бесполезные ссылки, которые все еще имеют путь к корневому набору выделения (я считаю, что хеш-таблицы - хороший способ оставить эти вещи запоздалыми). Вы можете попытаться включить явные вызовы GC в своем коде и убедиться, что (насколько это возможно) не храните вещи в глобальных переменных.

...