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?



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

Один короткий вопрос. Пусть настало время сборки. При этом в куче лежит 1000 объектов, а со стека есть две ссылки на два объекта в куче, которые в свою очередь не ссылаются больше ни на какие другие объекты. Вопрос, сколько объектов при этом обойдёт простой копирующий сборщик мусора?

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

Вопрос, сколько объектов при этом обойдёт простой копирующий сборщик мусора?

Ты не понял смысла моих последних постов?

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

Забавно, похоже это их общая черта. Можно посмотреть код?

И как эту проблему решают в языках без tco?

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

Мне, знаешь ли, плевать на эту ошибку в транскрипции. Тем более, что она не отменяет написанных тобой глупостей.

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

При чем тут C, правда?

У тебя в C указатели непосредственно на блок памяти.

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

На самом деле, я думаю, что есть библиотека для C, реализующая GC, но тогда там пришлось бы использовать не указатели, а какую-то обертку над ними, или указатель на указатель, в таком случае можно было б легко обновить все ссылки на перемещенный объект.

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

Не знаю насчет каждый раз, но вообще так делает, мб по достижении определённой памяти.

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

Ещё есть (был?) C++/CLI, не к ночи будь помянут.

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

Разве я ошибаюсь в том, что Swift нацелен на «обычную» десктопную разработку под яблочные ОСи

Ошибаешься. Десктоп у Apple сегодня это дополнение к мобильной ОС. Практически весь доход они получают от iPhone-ов и на них главный фокус.

а значит предполагает простую разработку и большое сообщество легкозаменяемых разработчиков

Это верно.

А если не ошибаюсь, то мне совершенно неясно, зачем отказываться от сборки мусора.

Автоматический подсчёт ссылок совсем ненамного сложнее автоматической сборки мусора для программиста, а по требованиям к памяти значительно оптимальней. Для того, чтобы сборка мусора работала со скоростью того же порядка, что и ручное управление памятью, программа должна использовать примерно в два раза больше памяти, чем ей реально нужно. На мобильных платформах это критично. В принципе это легко проверяется — сравни, сколько памяти на флагманах Apple и на флагманах Samsung при сравнимом функционале и производительности.

Кроме того в OS X раньше был сборщик мусора. Сейчас его вроде убрали. Видимо с Cocoa он плохо сочетается, проще научить всех программистов пользоваться ARC.

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

Мне, знаешь ли, плевать на эту ошибку в транскрипции.

То есть тебе нравится лишний раз продемонстрировать свою безграмотность?

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

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

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

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

Именно. Но память без объектов - пожалуйста. Так зачем обходить мертвые объекты?

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

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

Не каждый раз, возможно. Но так делают. Зато получаем 0 стоимость выделения памяти.

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

Теперь давай процитируй и прокомментируй вторую часть моего поста. Или лучше всё таки пойди и почитай умные книжки. Ты бы ещё к запятым, которые я постоянно пропускаю, прицепился.

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

При чем тут C, правда?

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

На самом деле, я думаю, что есть библиотека для C, реализующая GC

Ты прямо блещешь эрудицией.

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

То есть по-твоему в C используют malloc/free потому что не знают, что можно просто несколько раз сделать memmove и не париться?

Ты с ума сошел? Ты, в общем случае, не знаешь и не умеешь перемещать данные в Си. Это может сделать только сам программист, который решает задачу. Из-за указателей, которые «поедут» при перемещении. Потому на уровне библиотеки для выделения/освобождения памяти нельзя сделать лучше. Опять же, неясно, когда перемещать.

И для C есть сборщики, но не перемещающие.

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

Я не только умные книжки изучал, а ещё и программирую на java, так что не надо мне тут ссать в уши, ок?

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

Я не только умные книжки изучал, а ещё и программирую на java, так что не надо мне тут ссать в уши, ок?

А ты не мог бы еще раз сформулировать, какое утверждение ты отстаиваешь или пытаешься доказать?

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

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

Не бесплатная и не атомарная. И что дальше? Сборка мусора запускается не так часто. Есть специальные алгоритмы параллельной сборки, сборки для RT систем и т.д. и т.п. Зато константная и малая цена выделения памяти, нулевая(почти, там есть свои нюансы, но мы пока их касаться не будем, не разобрались еще на элементарном уровне с тобой) цена копирования ссылок. RC - тормоз еще тот.

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

Из-за указателей, которые «поедут» при перемещении.

Да указатели окуда взялись то? Почему архитектора фон-Неймана вообще, а не Тьюринга например?

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

Автоматический подсчёт ссылок совсем ненамного сложнее автоматической сборки мусора для программиста

Вот тут можно поспорить... Даже в сообществе Rust, которое, вроде как более «системное», это вызывало трудности...

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

А ты не мог бы еще раз сформулировать, какое утверждение ты отстаиваешь или пытаешься доказать?

Утверждение что сборщик мусора должен обойти каждый объект минимум один раз.

Каждый живой объект, каждый мертвый или то и другое вместе?

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

Утверждение что сборщик мусора должен обойти каждый объект минимум один раз.

И ты так это и не подтвердил ничем.

Для начала ответь на простой вопрос. Зачем сборщику мусора обходить мертвые объекты и как ты себе это представляешь?

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

То и другое. Для мертвых он должен как минимум вызвать finalize(). Плюс управлять памятью в реальной жизни.

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

Это именно ответ. В реальной жизни такой сборщик не используется по причине крайней неэффективности.

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

ARC намного проще Rust-а для программиста. Это совсем разные модели. ARC в общем случае имеет худшую производительность, потому что во-первых нужно на каждое присваивание указателя увеличивать/уменьшать счётчик ссылок (причём атомарно, а это дополнительных расходы), во-вторых нужно, собственно, хранить этот счётчик ссылок для каждого объекта. В Rust все эти расходы во время выполнения программы нулевые за счёт усложнения языка и жизни программиста.

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

Для начала ответь на простой вопрос. Зачем сборщику мусора обходить мертвые объекты и как ты себе это представляешь?

Дислексия мучает? Вот например:

protected void finalize() throws Throwable Called by the garbage collector on an object when garbage collection determines that there are no more references to the object.

http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#finalize()

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

Но у мертвых-то не у всех есть finalize, более того, чаще классы не определяют finalize.

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

Это именно ответ. В реальной жизни такой сборщик не используется по причине крайней неэффективности.

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

P.S. Ты у половины ЛОРа умудрился фейспалмы вызвать. Хз как у тебя это получилось.

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

P.S. Ты у половины ЛОРа умудрился фейспалмы вызвать. Хз как у тебя это получилось.

Ты даже не знаешь сколько это - половина ЛОРа, а утверждаешь.

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

И к чему ты это сюда привёл? Ты заявил, что копирующий GC не применяется в реальном мире по причине своей неэффективности. Я привёл тебе пример одного реально используемого копирующего GC. Причём тут твоя жаба?

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

Я привёл тебе пример одного реально используемого копирующего GC. Причём тут твоя жаба?

При том, что как раз моя жаба и используется, а не твой хаскель. И ещё .NET используется, но там тоже, как ни странно, никаких копирующих сборщиков в вакууме. Точнее, копирование используется, но для других целей.

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

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

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

Раз на этом написан ЛОР, это, безусловно, аргумент в пользу факта, что жаба - это глобально, быстро и надёжно, а программисты, пишущие на ней, являются безусловными гениями поголовно.

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

Эээ... какого комментария ты ждешь? Странно, что программа падает по Illegal instruction, но, по моему пониманию, реализованный таким образом список пытается удалять свой хвост рекурсивно и должен переполнять стек, если хвост длинный. Можно написать свою реализацию drop, которая будет делать всё итеративно - не могу сказать.

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

Я привёл тебе пример одного реально используемого копирующего GC. Причём тут твоя жаба?

этот клоун даже не в курсе, что в джаве GC тоже по большей части копирующие

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

ИМХО, код идиоматичен (хотя я не практикующий программист на Rust, чтобы утверждать это уверенно); код валиден, ибо компилируется.

tailgunner ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.