Замыкания и Reference Counting
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 03.07.21 11:22
Оценка:
Когда "замыкания" "захватывают контекст", создаётся структура в какой-то памяти, и эту память надо в последствии освободить.
Достаточно ли для этого применять Reference Counting или обязательно потребуется полномасштабная Garbage Collection ?
Re: Замыкания и Reference Counting
От: flаt  
Дата: 03.07.21 11:25
Оценка: 6 (1) +1
Здравствуйте, Эйнсток Файр, Вы писали:

ЭФ>Когда "замыкания" "захватывают контекст", создаётся структура в какой-то памяти, и эту память надо в последствии освободить.

ЭФ>Достаточно ли для этого применять Reference Counting или обязательно потребуется полномасштабная Garbage Collection ?

Rust и С++ обходятся без GC.
Re[2]: Замыкания и Reference Counting
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 03.07.21 12:00
Оценка: -2 :)
F> С++ обходятся без GC

C++ плохо обходится. Из-за него написали Java-у.
Re[3]: Замыкания и Reference Counting
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 03.07.21 16:50
Оценка: +4
Здравствуйте, Эйнсток Файр, Вы писали:

F>> С++ обходятся без GC


ЭФ>C++ плохо обходится. Из-за него написали Java-у.


Не из-за него, а из-за тех, кто пытался использовать C++, не имея для этого должной квалификации.
Re: Замыкания и Reference Counting
От: Alexander G Украина  
Дата: 04.07.21 17:37
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:

ЭФ>Достаточно ли для этого применять Reference Counting или обязательно потребуется полномасштабная Garbage Collection ?


Если говорить об автоматическом котроле жизни захваченных ссылок,
то стандартная проблема Reference Counting в том, что можно суметь сделать циклическую ссылку.
С замыканиями тоже — ссылку на замыкание можно поместить либо напрямую в захваченный объект, либо сделать более косвенный круг ссылок.

Если о не автоматическом, как в C++, то можно захватить shared_ptr или weak_ptr по значению, и будет Reference counting.
Разумеется, отвественность за отсуствие циклических ссылок в этом случае на авторе.
Русский военный корабль идёт ко дну!
Re[3]: Замыкания и Reference Counting
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 04.07.21 18:01
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:

F>> С++ обходятся без GC


ЭФ>C++ плохо обходится. Из-за него написали Java-у.


В C++ содержимое std::function копируется или перемещается по необходимости.
The God is real, unless declared integer.
Re: Замыкания и Reference Counting
От: vsb Казахстан  
Дата: 04.07.21 18:03
Оценка:
С замыканиями очень просто создать циклическую ссылку. Reference counting будет работать, но нужно не забывать руками рвать циклы. С GC это всё, конечно, намного проще.
Re: Замыкания и Reference Counting
От: cppguard  
Дата: 04.07.21 23:53
Оценка: +1
Здравствуйте, Эйнсток Файр, Вы писали:

ЭФ>Когда "замыкания" "захватывают контекст", создаётся структура в какой-то памяти, и эту память надо в последствии освободить.

ЭФ>Достаточно ли для этого применять Reference Counting или обязательно потребуется полномасштабная Garbage Collection ?

Замыкания аналогичны созданию класса с конструктором, который принимает элемент замыкания в качестве аргумента, поэтому вопрос про GC не совсем корректен. Подсчёт ссылок нельзя использовать в том случае, когда возможны циклические связи, но с замыканиями это никак не связано. Например есть контекст A, внутри которого есть переменная B и создаётся замыкаение С, с захватом переменной B. Получаются связи A -> B, A -> C, C -> B, цикла нет. Но если, например, замыкание захватывает сам контекст, то тут уже явная цикличность, и без сборки мусора не обойтись.
Re: Замыкания и Reference Counting
От: Worminator X Россия #StandWithPalestine 🖤🤍💚
Дата: 19.10.24 12:48
Оценка: 2 (1) :)
Здравствуйте, Эйнсток Файр, Вы писали:

ЭФ>Когда "замыкания" "захватывают контекст", создаётся структура в какой-то памяти, и эту память надо в последствии освободить.

ЭФ>Достаточно ли для этого применять Reference Counting или обязательно потребуется полномасштабная Garbage Collection ?

В языке Swift для MacOS и гейфонов, например, используются замыкания: https://swiftbook.org/docs/zamykaniya/
Он компилируется в нативный код, и никакого GC не содержит (для управления памятью применяется автоматический reference counting).
Как запру я тебя за железный замок, за дубовую дверь окованную,
Чтоб свету божьего ты не видела, мое имя честное не порочила…
М. Лермонтов. Песня про царя Ивана Васильевича, молодого опричника и удалого купца Калашникова
Re[2]: Замыкания и Reference Counting
От: Worminator X Россия #StandWithPalestine 🖤🤍💚
Дата: 19.10.24 12:54
Оценка: -1
Здравствуйте, vsb, Вы писали:

vsb>С замыканиями очень просто создать циклическую ссылку. Reference counting будет работать, но нужно не забывать руками рвать циклы. С GC это всё, конечно, намного проще.


Обычно для этого захватываемые переменные (поля объекта-замыкания) делают неизменяемыми, например, такое долгое время было в Java.
В результате присвоить им значение функции с замыканиями нельзя, и циклические ссылки невозможны.
Там, где зачем-то возможны (сложно придумать такую задачу), скорее всего, без GC не обойтись.
Как запру я тебя за железный замок, за дубовую дверь окованную,
Чтоб свету божьего ты не видела, мое имя честное не порочила…
М. Лермонтов. Песня про царя Ивана Васильевича, молодого опричника и удалого купца Калашникова
Re[3]: Замыкания и Reference Counting
От: vsb Казахстан  
Дата: 19.10.24 18:32
Оценка:
Здравствуйте, Worminator X, Вы писали:

vsb>>С замыканиями очень просто создать циклическую ссылку. Reference counting будет работать, но нужно не забывать руками рвать циклы. С GC это всё, конечно, намного проще.


WX>Обычно для этого захватываемые переменные (поля объекта-замыкания) делают неизменяемыми, например, такое долгое время было в Java.


В Java и сейчас так (та ещё дурость).

WX>В результате присвоить им значение функции с замыканиями нельзя, и циклические ссылки невозможны.


Поле неизменяемое, а содержимое изменяемое.

final var reference = new AtomicReference<>();
Runnable runnable = () -> System.out.println(reference.get());
reference.set(runnable);


WX>Там, где зачем-то возможны (сложно придумать такую задачу), скорее всего, без GC не обойтись.


Везде сплошь и рядом.
Отредактировано 19.10.2024 18:34 vsb . Предыдущая версия . Еще …
Отредактировано 19.10.2024 18:34 vsb . Предыдущая версия .
Re[4]: Замыкания и Reference Counting
От: Worminator X Россия #StandWithPalestine 🖤🤍💚
Дата: 20.10.24 21:49
Оценка: 1 (1)
Здравствуйте, vsb, Вы писали:

vsb>В Java и сейчас так (та ещё дурость).


У меня на рабочем проекте (OpenJDK 21) компилируется без ошибок:
    private void filterBy_SubjectTypeCode_Inn(@NonNull TARLSubjectInfoGetListInParam subjectSet,
                                              @NonNull List<GoldSubjectRecord> goldSubjectRecords) {
        if (subjectSet.getCommon() != null) {
            Integer idSubjectType = idTypeCacheService.getIdType(subjectSet.getCommon().getSSubjectTypeCode());
            String sInn = subjectSet.getCommon().getSInn();
            if (idSubjectType != null && sInn != null) {
                mdmDataManageService
                        .getTarantoolObjectByField("sINN", sInn, GoldSubjectRecord.class)
                        .stream()
                        .filter(record -> record.getIdSubjectType().equals(idSubjectType))
                        .forEach(goldSubjectRecords::add);
            }
        }
    }

Раньше обязательно требовало final для таких переменных.

vsb>Поле неизменяемое, а содержимое изменяемое.


В Java полно подобных косяков, к сожалению. Язык из костылей, прямо аналог Linux в мире ЯП. Но там как раз GC, разруливающий циклические зависимости.
Как запру я тебя за железный замок, за дубовую дверь окованную,
Чтоб свету божьего ты не видела, мое имя честное не порочила…
М. Лермонтов. Песня про царя Ивана Васильевича, молодого опричника и удалого купца Калашникова
Re[5]: Замыкания и Reference Counting
От: vsb Казахстан  
Дата: 21.10.24 02:58
Оценка: 1 (1)
Здравствуйте, Worminator X, Вы писали:

vsb>>В Java и сейчас так (та ещё дурость).


WX>У меня на рабочем проекте (OpenJDK 21) компилируется без ошибок:

WX>
    private void filterBy_SubjectTypeCode_Inn(@NonNull TARLSubjectInfoGetListInParam subjectSet,
WX>                                              @NonNull List<GoldSubjectRecord> goldSubjectRecords) {
WX>        if (subjectSet.getCommon() != null) {
WX>            Integer idSubjectType = idTypeCacheService.getIdType(subjectSet.getCommon().getSSubjectTypeCode());
WX>            String sInn = subjectSet.getCommon().getSInn();
WX>            if (idSubjectType != null && sInn != null) {
WX>                mdmDataManageService
WX>                        .getTarantoolObjectByField("sINN", sInn, GoldSubjectRecord.class)
WX>                        .stream()
WX>                        .filter(record -> record.getIdSubjectType().equals(idSubjectType))
WX>                        .forEach(goldSubjectRecords::add);
WX>            }
WX>        }
WX>    }

WX>Раньше обязательно требовало final для таких переменных.

Сейчас тоже требует. Просто это называется effectively final. Типа писать не обязательно, но оно подразумевается, менять ты её не можешь. Это ещё одна дурость.

vsb>>Поле неизменяемое, а содержимое изменяемое.


WX>В Java полно подобных косяков, к сожалению. Язык из костылей, прямо аналог Linux в мире ЯП. Но там как раз GC, разруливающий циклические зависимости.


Так в 99% языков нет понятия константности. И в 1% эта константность порой на уровне "я обещаю" и легко её убрать.
Отредактировано 21.10.2024 2:59 vsb . Предыдущая версия .
Re[3]: Замыкания и Reference Counting
От: пффф  
Дата: 22.10.24 11:16
Оценка: -1
Здравствуйте, Эйнсток Файр, Вы писали:

F>> С++ обходятся без GC


ЭФ>C++ плохо обходится. Из-за него написали Java-у.


Отлично обходится. И Java-у написали не из-за него
Re[2]: Замыкания и Reference Counting
От: · Великобритания  
Дата: 22.10.24 19:39
Оценка:
Здравствуйте, Worminator X, Вы писали:

ЭФ>>Когда "замыкания" "захватывают контекст", создаётся структура в какой-то памяти, и эту память надо в последствии освободить.

ЭФ>>Достаточно ли для этого применять Reference Counting или обязательно потребуется полномасштабная Garbage Collection ?
WX>В языке Swift для MacOS и гейфонов, например, используются замыкания: https://swiftbook.org/docs/zamykaniya/
WX>Он компилируется в нативный код, и никакого GC не содержит (для управления памятью применяется автоматический reference counting).
Ичсх чуда не получается: https://medium.com/@muzammalshahzad494/understanding-memory-leaks-caused-by-closures-in-swift-fd4358128d84
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[6]: Замыкания и Reference Counting
От: · Великобритания  
Дата: 22.10.24 19:46
Оценка: +1
Здравствуйте, vsb, Вы писали:

vsb>Сейчас тоже требует. Просто это называется effectively final. Типа писать не обязательно, но оно подразумевается, менять ты её не можешь. Это ещё одна дурость.

Это не дурость, а минимизации wtf/LoC. В шарпе и js с этим налажали и там это классическая грабля.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 22.10.2024 19:49 · . Предыдущая версия .
Re[7]: Замыкания и Reference Counting
От: vsb Казахстан  
Дата: 23.10.24 01:05
Оценка:
Здравствуйте, ·, Вы писали:

vsb>>Сейчас тоже требует. Просто это называется effectively final. Типа писать не обязательно, но оно подразумевается, менять ты её не можешь. Это ещё одна дурость.

·>Это не дурость, а минимизации wtf/LoC

Дурость, натуральная.

Во-первых никакой необходимости в этом всём вообще нет. Заменяем int x на int[] x = new int[1], все обращения к x на x[0] и готово, у нас с абсолютно тривиальным преобразованием работает изменение переменной из замыкания.

Во-вторых, даже если разработчики Java с чего-то решили, что теперь их миссия — zero overhead abstractions (ха-ха) и превращать под капотом переменную в массив это не ок, то никакой проблемы написать final у нужной переменной нет и это как раз уменьшает WTF/LoC. Т.е. необходимости ввода effectively final концепции не было никакой. Нужна тебе final переменная — ну и напиши final. Это как вводить effectively int концепцию — если не указали у переменной тип, то она будет считаться int-ом. Зачем? Какую проблему решает? Непонятно.

> В шарпе и js с этим налажали и там это классическая грабля.


Это вообще другая проблема и эту проблему так же легко исправить. В Go, кстати, исправили в одной из последних версий.
Отредактировано 23.10.2024 1:06 vsb . Предыдущая версия . Еще …
Отредактировано 23.10.2024 1:05 vsb . Предыдущая версия .
Re[8]: Замыкания и Reference Counting
От: · Великобритания  
Дата: 23.10.24 10:01
Оценка: +1
Здравствуйте, vsb, Вы писали:

vsb>Дурость, натуральная.

vsb>Во-первых никакой необходимости в этом всём вообще нет. Заменяем int x на int[] x = new int[1], все обращения к x на x[0] и готово, у нас с абсолютно тривиальным преобразованием работает изменение переменной из замыкания.
Необходимость не техническая, а семантическая. Чтобы по коду было интуитивно понятно что происходит. Замена значения на стеке полем в объекте — имеет конкретные последствия и работает единообразно для всего, никаких особых случаев для лямбд нет.

vsb>Во-вторых, даже если разработчики Java с чего-то решили, что теперь их миссия — zero overhead abstractions (ха-ха) и превращать под капотом переменную в массив это не ок, то никакой проблемы написать final у нужной переменной нет и это как раз уменьшает WTF/LoC. Т.е. необходимости ввода effectively final концепции не было никакой. Нужна тебе final переменная — ну и напиши final. Это как вводить effectively int концепцию — если не указали у переменной тип, то она будет считаться int-ом. Зачем? Какую проблему решает? Непонятно.

effectively final — небольшой сахарок, позволяющий выводить final автоматически во время компиляции и возможность его не писать его явно. В каком-то смысле аналог var.

>> В шарпе и js с этим налажали и там это классическая грабля.

vsb>Это вообще другая проблема и эту проблему так же легко исправить.
Проблема в том, что неоднозначно что в какой момент должно меняться. Поэтому явное требование финальности — заставляет писать код, в котором всё становится явным.

vsb>В Go, кстати, исправили в одной из последних версий.

Любопытно, как?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[9]: Замыкания и Reference Counting
От: vsb Казахстан  
Дата: 23.10.24 17:48
Оценка:
Здравствуйте, ·, Вы писали:

vsb>>В Go, кстати, исправили в одной из последних версий.

·>Любопытно, как?

https://go.dev/blog/loopvar-preview

https://go.dev/doc/go1.22#language
Отредактировано 23.10.2024 17:49 vsb . Предыдущая версия .
Re[10]: Замыкания и Reference Counting
От: · Великобритания  
Дата: 23.10.24 20:25
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>>>В Go, кстати, исправили в одной из последних версий.

vsb>·>Любопытно, как?
vsb>https://go.dev/blog/loopvar-preview
Это мелочь и фигня. Такой ошибки в java просто не было. А чуток добавить сахарку — недавно начали работу https://bugs.openjdk.org/browse/JDK-8341785

Кстати, это, конечно, отстой, что go не парится о backward compatibility и позволяет себе изменения, которые могут вызвать незаметные изменения в поведении кода после смены версии компилятора. В java такого вроде не припомню.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 23.10.2024 21:05 · . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.