2013-05-06 6 views
1

От the pickaxe:Должен ли я использовать ALLOCA_N, если я сам выпущу память?

Вы можете иногда нужно выделить память в расширении тха т не будет использоваться для хранения объектов, возможно, у вас есть гигантское растровое изображение для Bloom фильтра, изображения или целая куча небольших структур, которые Ruby не использует напрямую. Чтобы правильно работать с сборщиком мусора, , вы должны использовать следующие процедуры распределения памяти. Эти подпрограммы выполняют немного больше работы, чем функция stardard malloc. Например, если ALLOC_N определяет, что он не может выделить желаемое количество memy, он будет вызывать сборщик мусора, чтобы попробовать , чтобы вернуть некоторое пространство. Это поднимет NoMemError, если он не может или если запрашиваемый объем памяти неверен

Но в данной функции, я точно знаю, когда выпуск памяти. В этом случае, должен ли я использовать ALLOC_N для распределения памяти?

Есть ли законные случаи, когда я должен освобождать память самостоятельно, или лучше всегда использовать ALLOC_N и не заботится об этом?

ответ

1

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

Если вы просто создаете что-то, а затем выбрасываете его, все в контексте вызова одного сложного метода, то вы можете использовать простые подходы C для управления памятью. C-файл отлично подходит для реальных основ. просто объявите int foo[1000];, и вы можете использовать этот массив внутри, C будет использовать стек и очистить как обычно - Ruby, конечно, не имеет доступа к этим данным, если вы не скопируете его в чем-то в конце. Не переусердствуйте, хотя, int foo[1000000]; рискует взорвать стек и вызвать segfault.

Документация подразумевает еще одну причину использования ALLOC_N - вы избежите из-за нехватки памяти из-за вызова сбора мусора. Кроме того, вы получите немного более дружелюбный процесс, зависящий от Ruby, если вы действительно потеряли память (в отличие от того, что сделает ваша C-процедура).

3

ALLOC_N не освобождает выделенную память. Если при первой попытке выделить память вы сработали, это вызовет GC, пытаясь освободить больше памяти, а затем повторите попытку.

Вы должны освободить память, выделенную ALLOC_N. Но используйте xfree вместо free - это не так хорошо описано в руководствах, таких как http://www.ruby-doc.org/docs/ProgrammingRuby/html/ext_ruby.html, но вы обнаружите, что оно используется в источнике Ruby и источнике других Ruby C Extensions.

+1

Хороший блог, который объясняет C Расширения: http://blog.aeolusproject.org/category/ruby/page/2/ – thomthom

+0

Более новой функцией может быть использование 'ruby_xfree'. – thomthom

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