alloca и ObjectiveC Сборщик мусора - PullRequest
1 голос
/ 04 декабря 2009

В целевом проекте C с включенным GC я размещаю массив с переменным размером в стеке так:

MaValue *myStack = alloca((sizeof(id) * someLength));

(причина, по которой я хочу это сделать, не важна :) Затем, внутри цикла, я нажимаю и вставляю материал в / из myStack. Некоторые вещи, которые я помещаю в стек, - это новые объекты, на которые больше не ссылаются.

Мои интуитивные ощущения говорят мне, что целевой сборщик мусора C не знает об этих указателях и поэтому собирает новые (в противном случае не связанные) объекты. Часть этого убеждения исходит из того, что цель C GC на самом деле не консервативна, а «знает свои указатели» (например, через карту стека).

Однако во всех моих экспериментах (вставляя вызовы [[NSGarbageCollector defaultCollector] collectExhaustively]) я не получал эти объекты для сбора - что хорошо, но неожиданно. Похоже, что GC сканирует весь стек и, например, консервативно предполагает, что целое число, имеющее значение действительного указателя, действительно является указателем.

Это правильно? Или я что-то упустил?

1 Ответ

3 голосов
/ 04 декабря 2009

ведет себя правильно.

В то время как сборщик сканирует кучу точно [в максимально возможной степени], поскольку каждый класс имеет макет и сканируются только слоты, которые ссылаются на объекты или используют __strong, стек должен сканироваться консервативно. Каждый слот размером с указатель и выровненный с указателем слот в стеке должен быть отсканирован на наличие ссылок.

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

На самом деле вам вообще не следует использовать alloca (). Даже на странице руководства написано

Функция alloca () является машинной и зависит от компилятора; его использование обескураженный.

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

...