Подтвердить что ты не робот

В Ruby, что хранится в стеке?

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

Кроме того, если это так, что переменные выделяются в стеке и содержат только скрытые указатели, сколько байтов используют сами переменные (без учета объектов, на которые они указывают)?

Edit:

Этот вопрос был задан, потому что я пытался выяснить, будет ли ограничение на стек оптоволокна 4kB проблемой в этом вопросе. Кажется, что (с MRI 1.9.3), что каждая переменная сама потребляет один байт, и есть небольшая служебная информация, связанная с волокном, которая уменьшает доступный размер стека на несколько байтов.

Этот код не будет выполнен на 4045-й итерации:

count = 0
loop do
  count += 1
  puts count
  varlist = String.new
  count.times do |i|
    varlist += "a#{i} = 1\n"
  end
  s = "fiber = Fiber.new do \n #{varlist} \n end \n fiber.resume"
  eval(s)
end
4b9b3361

Ответ 1

Это зависит от реализации Ruby.

Например, Ruby 2.0 MRI (типичный для большинства систем) хранит все его объекты в кучах. Маленькие объекты, такие как короткие струны, могут полностью помещаться в кучи. Для больших объектов Ruby будет выделять дополнительную память за пределами кучи.

См. "Распределение памяти МРТ - основа для разработчиков" и "Демистификация Ruby GC"

Здесь "Понимание того, как Ruby хранит объекты в памяти" , который имеет большое и длинное описание:

"Все пространство, которое объект занимает в памяти, не хранится внутри слота. Скорее, каждый слот представляет собой небольшое пространство фиксированного размера, которое можно рассматривать как интерпретатор Ruby для определения местоположения в памяти. самой Ruby Heap и содержит реальное" мясо "объекта. Чтобы быть ясным, если у вас есть строка 50 МБ - 50 МБ данных хранятся за пределами Ruby Heap. Если вы действительно хотите узнать историю о 50 МБ, пространство для него фактически выделяется чем-то вроде команды malloc в C (поскольку хороший ol" Ruby написан на C), а затем сохранен в системной куче. Слот в Ruby Heap просто содержит ссылку на эту ячейку памяти в системе Куча, которая содержит 50 МБ данных. "

" Ruby имеет собственное управление кучей, которое на самом деле состоит из нескольких "Ruby Heaps" для управления объектами, созданными во время выполнения программы Ruby, это отдельно от системной кучи для вашей операционной системы. Каждая отдельная Ruby Heap содержит слоты, с каждым слотом, способным к одной ссылке один объект.

Другим хорошим источником является "Как Ruby управляет сборкой памяти и мусора ", которая ссылается на слайды на "" Снежинки для мусора "из LA Ruby Conference".

"Как сборник мусора, Ruby берет легкий путь, помещая все в кучу".

Волокна

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

"В отличие от других моделей без штабелирования без веса concurrency, каждый волокно поставляется с небольшим стеком в 4 КБ, что позволяет прерывать волокно от глубоко вложенных вызовов функций внутри оптоволоконного блока".

Вам может быть интересен долгосрочный запрос функции для динамического определения размера стека.

Если вас больше интересует реальное решение, автор запроса функции рекомендует это обходное решение: "реорганизовать операцию, которая требует, чтобы большой стек выполнялся в отдельном потоке, а затем блокировал thread.value".

Вы также можете рассмотреть возможность компиляции пользовательской версии Ruby с собственными выборками для FIBER_MACHINE_STACK_ALLOCATION_SIZE и FIBER_VM_STACK_SIZE в исходном файле cont.c. В этом файле также показано, как выделяются, освобождаются и удаляются стеки волокон.