LINUX.ORG.RU

Этот ваш reference counting

 ,


1

4

Во время попытки доказать одному товарищу, что Swift — ненужно, я наткнулся на интересную особенность:

import Foundation

let noLeak = 131028
let withLeak  = noLeak*10

class R {
    var _a : R?
    init(a : R?) {
        _a = a
    }
}

func test(n:Int, leak:Bool) {
    var p0 = R(a : nil)
    var p = R(a : p0)
    for _ in 1...n {
        p = R(a : p)
    }
    if leak {
        p0._a = p
    }
}

test(withLeak, true)
println("Evil leaking function")
test(noLeak, false)
println("Good function")

Первый вызов test просто течёт в лучших традициях Reference Counting, а вот второй падает со stack overflow (деаллокация, похоже, делается рекуррентно).

Интересно, есть ли такое же в Rust?


Ответ на: комментарий от anonymous

Arc, в большинстве случаев (во время компиляции то есть - ред.), тормознее, чем реализация с gc.

Ах, ну конечно GC быстрее всех. Поэтому и возникают такие вот вопросы: http://stackoverflow.com/questions/6005865/prevent-net-garbage-collection-for...

asaw ★★★★★ ()
Последнее исправление: asaw (всего исправлений: 2)
Ответ на: комментарий от asaw

ты читать не умеешь? по живым надо пройтись, по мусору ходить не нужно.

maloi ★★★★★ ()
Ответ на: комментарий от hateyoufeel

Это очень интересный вопрос, на самом деле.

Да нет ничего интересно. Аллокация в компактифицирующем сборщике - простое смещение указателя (то есть на порядок быстрее системного маллока), деаллокация - nop, то есть мгновенна. Память системе для оптимизации можно не возвращать вовсе.

anonymous ()
Ответ на: комментарий от asaw

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

Не по всем, а только по достижмым. Если же достижимых объектов нет (например навыделяли 2гб во время работы алгоритма и алгоритм завершился), то сборка мгновенна.

anonymous ()
Ответ на: комментарий от asaw

мусор - он и есть мусор, с ним ничего делать не надо, можно сразу поверх него писать новые данные.

maloi ★★★★★ ()
Ответ на: комментарий от asaw

И кстати это ещё даже не вспоминая про поколения. Если идет сборка в молодом поколении, то в старое можно вообще не заглядывать.

maloi ★★★★★ ()
Ответ на: комментарий от fmdw

в 1.1.0 у меня

thread '<main>' has overflowed its stack
Process didn't exit successfully: `target/debug/list` (signal: 4)

maloi ★★★★★ ()
Ответ на: комментарий от maloi

А про управление памятью ты что-нибудь слышал?

asaw ★★★★★ ()
Ответ на: комментарий от asaw

Ты решил все слова, которые когда-то слышал сюда написать? молодец, много слов знаешь.
Иди читай код, если не веришь

maloi ★★★★★ ()
Ответ на: комментарий от maloi

При том, что само собой по волшебству ничего не происходит.

asaw ★★★★★ ()
Ответ на: комментарий от maloi

Про поколения это ты ляпнул, поэтому иди и читай почему major cycle никуда не девается.

asaw ★★★★★ ()
Ответ на: комментарий от asaw

ты прочитал, что я тебе писал-то?
или ты считаешь что каждый minor cycle сопровождается major cycle?

maloi ★★★★★ ()
Ответ на: комментарий от asaw

конечно не происходит, только управление памятью тут никаким боком.

maloi ★★★★★ ()
Ответ на: комментарий от anonymous

Аллокация в компактифицирующем сборщике - простое смещение указателя (то есть на порядок быстрее системного маллока)

В идеальном случае - да. В худшем случае придётся malloc/realloc делать.

деаллокация - nop, то есть мгновенна.

Опять же, это если объект не вышел из nursery или короткоживущей кучи. В долгоживущей куче всё будет хуже.

P.S. Я таки соглашусь, что, если забыть про особые случаи, то лучше использовать GC.

hateyoufeel ★★★★★ ()
Ответ на: комментарий от asaw

Это ты фигню написал, когда сказал что при сборке мусора нужно пройтись по всем объектам минимум один раз.
Или ты утверждаешь что при minor cycle перелопачивается вся куча?

maloi ★★★★★ ()
Ответ на: комментарий от maloi

Да, при сборке мусора по каждому объекту нужно пройтись минимум один раз. Если ты по объекту не проходишься, то сборки мусора нет. Точка.

asaw ★★★★★ ()
Ответ на: комментарий от asaw

при сборке мусора по каждому объекту нужно пройтись минимум один раз

Ты можешь объяснить зачем это делать?

hateyoufeel ★★★★★ ()
Ответ на: комментарий от asaw

Почему сам? Все, что недостижимо, то мертвое. Деструкторов нет, значит ничего делать не надо - это просто память. Для вызова финализаторов отдельные списки и с ними идет отдельная работа. Финализаторов обычно не так много.

anonymous ()
Ответ на: комментарий от hateyoufeel

Как минимум чтобы сделать вызов finalize (или Finalize, или аналогичный). Ваш К.О.

asaw ★★★★★ ()
Ответ на: комментарий от asaw

Как минимум чтобы сделать вызов finalize (или Finalize, или аналогичный). Ваш К.О.

Тебе уже выше написали, что это делается через отдельный список.

hateyoufeel ★★★★★ ()
Ответ на: комментарий от anonymous

Деструкторов нет, значит ничего делать не надо - это просто память.

Это просто память, которой надо управлять даже если ты её просишь у ОС один раз.

asaw ★★★★★ ()
Ответ на: комментарий от hateyoufeel

А зачем это вообще делается по-твоему?

asaw ★★★★★ ()
Ответ на: комментарий от asaw

Да, при сборке мусора по каждому объекту нужно пройтись минимум один раз. Если ты по объекту не проходишься, то сборки мусора нет. Точка.

Вот так вот, да? Точка и все. А аргументация не нужна?

Факт в том, что сборщик не проходит по всем объектам. Он ищет достижимые объекты. И обходит только их. Остальные объекты перестают существовать. А выделенная под них память используется или прямо под новые объекты или косвенно, когда мы осуществляем перемещение объектов в случае перемещающего сборщика.

anonymous ()
Ответ на: комментарий от asaw

finalize нет у большинства объектов. Для вызова используются отдельные механизмы и структуры. Не путай с деструкторами. Это совершенно разные вещи.

anonymous ()
Ответ на: комментарий от anonymous

Остальные объекты перестают существовать.

Проблема в том, что в твоей сказке об этом никто не знает.

asaw ★★★★★ ()
Ответ на: комментарий от asaw

Это просто память, которой надо управлять даже если ты её просишь у ОС один раз.

Но ты говоришь про объекты, а не память. Это разные вещи. Объектов больше нет. И никто их не обходит(потому, что их нет). Память переиспользуется, да. Сейчас, в основном, используют перемещающие сборщики, которые тоже работают только с существующими объектами, просто затирая память от старых.

anonymous ()
Ответ на: комментарий от asaw

А кому и зачем нужно об этом знать? У нас есть список доступных объектов и мы их перемещаем в начало кучи(условно). Зачем нам знать о том, что память, которую мы переиспользуем, когда-то принадлежала тому или иному объекту? Зачем нам обходить недостижимые объекты? Какую информацию они нам могут дать?

anonymous ()
Ответ на: комментарий от anonymous

Но ты говоришь про объекты, а не память. Это разные вещи.

Это разные вещи в фантазиях школьников. В реальном мире объекты без памяти е существуют.

asaw ★★★★★ ()
Ответ на: комментарий от anonymous

и мы их перемещаем в начало кучи(условно).

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

asaw ★★★★★ ()
Ответ на: комментарий от asaw

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

Я даже не знаю, что тебе сказать. Как минимум несколько реализаций GC для функциональных языков так и работают. Добро пожаловать в 2015 год.

P.S. Быстрое гугление выдало статью 1971 года (http://comjnl.oxfordjournals.org/content/15/3/204.full.pdf)

hateyoufeel ★★★★★ ()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Ага, здравствуйте, лунатики. То есть по-твоему в C используют malloc/free потому что не знают, что можно просто несколько раз сделать memmove и не париться? Это, знаешь ли, покруче, чем ходить по каждому объекту при сборке мусора.

asaw ★★★★★ ()
Ответ на: комментарий от asaw

Ага, здравствуйте, лунатики. То есть по-твоему в C используют malloc/free потому что не знают, что можно просто несколько раз сделать memmove и не париться? Это, знаешь ли, покруче, чем ходить по каждому объекту при сборке мусора.

Причём тут C?

hateyoufeel ★★★★★ ()
Ответ на: комментарий от hateyoufeel

Да так, ты вот про 1970-е годы вспомнил, вот и C.

asaw ★★★★★ ()
Ответ на: комментарий от asaw

потому что не знают, что можно просто несколько раз сделать memmove и не париться?

Указатели мешают, не?
Ну и обычную ГЦ-фигню, типа большего потребления памяти, никто не отменял. Или скорость или память — все, как всегда.

anonymous ()
Ответ на: комментарий от anonymous

Главное мир нужно периодически останавливать, чтоб он не вышел из-под контроля и все эти замечательные алгоритмы перемещения работали.

asaw ★★★★★ ()
Последнее исправление: asaw (всего исправлений: 1)
Ответ на: комментарий от asaw

Вот так точно никто не делает.

господин никогда не слышал про moving GC?

maloi ★★★★★ ()
Ответ на: комментарий от maloi

Ну если в твоем мире копирование/перемещение памяти - бесплатная атомарная операция, тогда слышал. А так нет.

asaw ★★★★★ ()
Ответ на: комментарий от asaw

Ну да, а malloc/free абсолютно бесплатны! :)

anonymous ()
Ответ на: комментарий от asaw

а кто говорил про то что копирование/перемещение бесплатно и атомарно? ты похоже с голосами в своей голове споришь.

maloi ★★★★★ ()
Ответ на: комментарий от asaw

Блин, может хватит уже демонстрировать свою безграмотность, почитай хоть что-то про архитектуру существующих сборщиков или хотя бы найди справку на параметры ххкопакт* для джирокета.

ya-betmen ★★★★★ ()
Ответ на: комментарий от maloi

а кто говорил про то что копирование/перемещение бесплатно и атомарно?

Да есть тут некоторые, которые не представляют себе сколько чего стоит. Пишут тут про мгновенный сбор мусора (буквально).

asaw ★★★★★ ()
Ответ на: комментарий от ya-betmen

Это ты демонстрируешь свою фанатичность. J читается как «джей», а «джи» - это G.

asaw ★★★★★ ()
Последнее исправление: asaw (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.