Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, ·, Вы писали:
EP>>>Не надо оправдываться абстрактными "OOM везде можно получить" — я так тоже умею: "везде можно получить расстрел памяти, даже при использовании Java" dot>>Расстрел памяти в Java? Как??? EP>Элементарно. Её может расстрелять сторонняя native библиотека, причём даже не из-за бага в самой библиотеке, а потому что Java код нарушил предусловия. Или например может расстрелять свой же Runtime — гарантии нет EP>Это аргумент примерно того же порядка что и "OOM везде можно получить" в ответ на описание конкретного use-case'а.
Ты описал юзкейс когда память освобождается медленнее чем потребляется. Не понимаю каким образом ты избежишь ООМ в таком случае в плюсах?
Если ты имеешь в виду, что gc выделенного времени не хватило чтобы освободить память, то jvm всегда даёт шанс gc прежде чем бросить ООМ исключение. Да, будет latency spike, но не ООМ. Но это бага конфигурации, исправляется.
EP>>>Как того требует задача. Если нужно ограничить время — то соответственно засекаешь время/тики, или что там удобнее. dot>>Время чего? Вот у тебя dot>>
dot>>smartPtr.release(); // упс, заняло 300ms, хотя обычно занимает 3us. Нам не повезло оказаться последним юзером объекта и граф объектов оказался больше обычного.
dot>>
EP>Не обязательно удалять весь граф сразу, можно по одному узлу, граф-остаток ставить в очередь.
А откуда ты знаешь какой там граф? В данном участке кода ты видишь только "smartPtr". Тебе придётся понимать структуру графа, размеры узлов, етс...
EP>>>Например в порядке очереди. dot>>Как выстоить в очередь граф объектов? EP>Например в деструкторе smart-pointer'а не сразу удалять, а ставить в очередь.
Если много мелких объектов — очереди поплохеет, будет хороший такой contention point.
EP>>>Нет, это неверно. Задача GC в первую очередь отличить reachable от unreachable объектов. А уж делать reclaim порциями, или за один присест — это уже отдельное свойство, причём ортогональное наличию/отсутствию GC. dot>>GC в Java это целый комплекс алгоритмов с тучей настроек. Задача — освобождать память от unreachable объектов, а не просто "отличить". EP>А ещё он внутри делает сложение целых чисел. Из этого не следует что сложение целых чисел это "переизобретание современного GC".
Ты задачу GC как-то странно определил. Не отличает он, а освобождает. Отличить — подзадача.
EP>>>И, кстати, для C++ возможен и runtime'овый GC (прям в стандарте есть специальное API), и библиотечный (я даже как-то делал for fun). dot>>Но как? Precise GC принципиально невозможен. EP>Возможен. Заводится отдельная GC Heap, все указатели на элементы внутри этой кучи заворачиваются в gc_ptr<T>. EP>Отличать root от не root можно разными способами. Например если сам объект-указатель типа gc_ptr находится не в этой куче — то это root. EP>AFAIR, нечто подобное используется в SpiderMonkey.
Я не понимаю чем "написать либу которая делает gc" и "написать jvm которая делает gc". Так хоть можно сказать, что и в маш-кодах gc есть.
dot>>>>Сам же написал "GC линеен от количества N живых объектов", т.е. сдохший шмат графа можно освобождать также за примерно O(1). EP>>>При этом сделав O(N) обход живых объектов, которого нет в случае с C++ dot>>В YG это N малО, а OG обходится не часто, EP>Чем больше N — тем чаще. В любом случае это не O(1).
Я имею в виду O(1) если N — количество дохлых объектов, для ситуации когда ты сказал "массив объектов, агрегирующих ... просто по сути один вектор освобождающийся за O(1)". Да, этот один вектор умирающий целиком будет освобождаться за O(1), т.е. независимо от размера этого самого вектора. Да, оно будет зависеть от наличия других живых объектов, но это не то, что я понял из этих твоих слов.
dot>>и обычно минимально влияя на основные потоки. EP>Memory throughput не бесконечная, более того — часто является bottleneck'ом. GC во время обхода интенсивно использует память, сужая этот bottleneck.
Пусть, для LL критичной системы gc будет работать на другом ядре, используя другой банк памяти (опять же, заметь, — ничего java specific).
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
EP>>>>Не надо оправдываться абстрактными "OOM везде можно получить" — я так тоже умею: "везде можно получить расстрел памяти, даже при использовании Java" dot>>>Расстрел памяти в Java? Как??? EP>>Элементарно. Её может расстрелять сторонняя native библиотека, причём даже не из-за бага в самой библиотеке, а потому что Java код нарушил предусловия. Или например может расстрелять свой же Runtime — гарантии нет EP>>Это аргумент примерно того же порядка что и "OOM везде можно получить" в ответ на описание конкретного use-case'а. dot>Ты описал юзкейс когда память освобождается медленнее чем потребляется.
Причём это происходит по вине самого GC.
dot>Не понимаю каким образом ты избежишь ООМ в таком случае в плюсах?
Нет линейной зависимости времени очистки от количества живых объектов. В случае же GC, на одной и той же скорости входящего потока он может либо успевать очищать, либо нет — и это сильно зависит от текущего количества живых объектов.
dot>Если ты имеешь в виду, что gc выделенного времени не хватило чтобы освободить память, то jvm всегда даёт шанс gc прежде чем бросить ООМ исключение. Да, будет latency spike, но не ООМ. Но это бага конфигурации, исправляется.
Так в это время (пока JVM даёт шанс) будут накапливаться всё новые и новые запросы, требующие всё новую и новую память. Это либо OOM либо DoS, а не просто spike.
EP>>>>Как того требует задача. Если нужно ограничить время — то соответственно засекаешь время/тики, или что там удобнее. dot>>>Время чего? Вот у тебя dot>>>
dot>>>smartPtr.release(); // упс, заняло 300ms, хотя обычно занимает 3us. Нам не повезло оказаться последним юзером объекта и граф объектов оказался больше обычного.
dot>>>
EP>>Не обязательно удалять весь граф сразу, можно по одному узлу, граф-остаток ставить в очередь. dot>А откуда ты знаешь какой там граф? В данном участке кода ты видишь только "smartPtr". Тебе придётся понимать структуру графа, размеры узлов, етс...
Зачем?
EP>>>>Например в порядке очереди. dot>>>Как выстоить в очередь граф объектов? EP>>Например в деструкторе smart-pointer'а не сразу удалять, а ставить в очередь. dot>Если много мелких объектов — очереди поплохеет, будет хороший такой contention point.
Очередь может быть thread local.
EP>>>>Нет, это неверно. Задача GC в первую очередь отличить reachable от unreachable объектов. А уж делать reclaim порциями, или за один присест — это уже отдельное свойство, причём ортогональное наличию/отсутствию GC. dot>>>GC в Java это целый комплекс алгоритмов с тучей настроек. Задача — освобождать память от unreachable объектов, а не просто "отличить". EP>>А ещё он внутри делает сложение целых чисел. Из этого не следует что сложение целых чисел это "переизобретание современного GC". dot>Ты задачу GC как-то странно определил. Не отличает он, а освобождает. Отличить — подзадача.
В любом случае, ты же говоришь что если делать отложенное очищение, то получаем GC. А если делать сразу почему тогда не GC? А если тоже считаешь что GC, зачем тогда вообще выделять отдельно случай с отложенным очищением?
EP>>>>И, кстати, для C++ возможен и runtime'овый GC (прям в стандарте есть специальное API), и библиотечный (я даже как-то делал for fun). dot>>>Но как? Precise GC принципиально невозможен. EP>>Возможен. Заводится отдельная GC Heap, все указатели на элементы внутри этой кучи заворачиваются в gc_ptr<T>. EP>>Отличать root от не root можно разными способами. Например если сам объект-указатель типа gc_ptr находится не в этой куче — то это root. EP>>AFAIR, нечто подобное используется в SpiderMonkey. dot>Я не понимаю чем "написать либу которая делает gc" и "написать jvm которая делает gc". Так хоть можно сказать, что и в маш-кодах gc есть.
Разница в том, что написанная библиотека используется внутри самого host-языка. То есть эти gc_ptr — они используется не внутри какой-то виртуальной среды созданной библиотекой, а внутри вызывающего host-языка.
dot>>>и обычно минимально влияя на основные потоки. EP>>Memory throughput не бесконечная, более того — часто является bottleneck'ом. GC во время обхода интенсивно использует память, сужая этот bottleneck. dot>Пусть, для LL критичной системы gc будет работать на другом ядре, используя другой банк памяти (опять же, заметь, — ничего java specific).
Какой другой банк памяти? Ему нужно обходить именно ту память, с которой работают полезные потоки, тем самым путаясь у них под ногами.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
dot>>>>Мало того, тот кому не повезло освобождать ссылку последним — не придётся тратить ВНЕЗАПНО время на освобождение, EP>>>Пусть просто поставит в очередь, делов-то dot>>Поставит что? Сразу весь развесистый граф? А если надо только часть освободить? Ставить каждый самый мелкий объект? А очереди не поплохеет? EP>Не каждый объект, а те которые не успеваем освободить.
А как мы будем выяснять — успеем или не успеем?
dot>>>>На java память ресурс другого типа. "Освобождать память" там нельзя. EP>>>А я поэтому и сказал конкретно "ресурс", а не просто "объект". Да и память не ресурс только если она не ограниченна — упрёшься в предел, получишь удар по latency, на который постоянно ссылаешься. dot>>В low latency единственный ресурс обычно память. EP>Сильное утверждение. Да и это проблема ко всему относится, а не только к low latency.
Что-то не понял. Которая проблема?
dot>>Из LL кода никто в своём уме коннекты к БД не открывает, с SOAP сервисам не обращается. EP>Файлы не открывают? Соединения не устанавливают?
Нет, конечно. С ума что-ли сошел? Кто ж файл будет открывать из LL треда?!
dot>>>>А для ресурсов в общем случае — наследники java.lang.ref.Reference. EP>>>Каким образом они обеспечат prompt finalization? dot>>А надо? EP>Надо, это задача.
Какая именно задача? Ты не путаешь задачу со способом решения?
dot>>А зачем вообще ресурсы обязательно освобождать из финалайзеров? EP>Освобождай откуда угодно, но покажи как это реализуется в Java.
dot>>Я не понял какую задачу ты описываешь. EP>Ту же самую, с потоками, при завершении последнего нужно освободить ресурс.
Эээ.. Попробую сформулировать. Открыть файл, раздать открытый файл пачке тредов, которые могут так же кидаться файлами с другими тредами и закрыть, когда последний тред его обработает. Так? Собственно решение будет аналогично С++, взять какой-нибудь подходящий класс из java.lang.concurrent.* и реализовать контроль пользователей ресурса.
Ещё раз, в java есть только один специально обрабатываемый ресурс — память. Не надо натягивать gc на контроль любых ресурсов, он только для памяти.
Я понимаю откуда растёт это заблуждение. Деструктор в С++ может быть использован как для памяти, так и для любых других ресурсов. Не надо переносить это понимание в java. В java gc — только для памяти. Другие ресурсы — с помощью try-with-resources контролируются.
dot>>>>Ну да... Только, как мне кажется. эти схемы гораздо проще если есть gc. EP>>>При GC чуть проще реализация lockfree структур данных, за счёт ABA, но при этом сами GC в большинстве своём не lockfree (lockfree GC видел только в статьях) — то есть тут уже большой терминологический вопрос, остаётся ли структура данных lockfree при не non-lockfree GC dot>>Если локи расставляются сами компилятором и лочится на предсказуемое время — почему бы и нет. EP>Потому что lock'и это не lockfree, принципиально. Смотри определение. Lockfree это прежде всего некоторые гарантии, а не например скорость — скорость вообще может быть меньше. EP>Да и кто сказал что время предсказуемо? Например GC заснул захватив lock, остальные ждут. Тут желательно хотя бы obstruction free
lockfree это гарантии на уровне кода, а что там делает окружение — не важно. Скажем, если операционка вытесняет твой поток — по сути она лочит его — исполнение приостанавливается. А ещё и CPU может заснуть, скажем для экономии энергии или для регуляции тепловыделения. И что? lockfree и на C++ невозможен?
В том то и дело, что gc в java это часть окружения для твоего кода, и отсутсвие дедлоков в lockfree коде можно гарантировать. Библиотечный gc в C++ — упс.
EP>>>Да и такие структуры должны реализовывать профессионалы своего дела, так как это трудная/опасная тема. dot>>В том то и дело. Это уже и реализовали в виде JVM — бери, да используй, а не изобретай велосипед. EP>А я предлагал изобретать? Я сказал что ABA проще решается при использовании GC, решать её при этом самому не обязательно.
Много что проще решается. Я тебе сразу сказал "Когда ответишь на эти вопросы и многие другие, то переизобретёшь современный gc."
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, Evgeny.Panasyuk, Вы писали:
dot>>Если VM оптимизатор видит, что объект используется только в одном месте, он переносит ссылку на стек, т.е. по сути выводит unique_ptr. EP>И не в покер, а в преферанс. И не выиграл, а проиграл. EP>И не ссылку, а сам объект. И не unique_ptr, а просто стэковый объект.
Перенос объекта на стек это другая оптимизация. Может делаться только для маленьких оъбектов. Если у тебя выделяется 100мб массив и EA покажет, что ссылка на массив не убегает за пределы, то при выходе из стека объект грохнется. Т.е. по сути тот же unique_ptr.
dot>>>>shared_ptr у треда-владельца, а "зависимые" — имеют weak_ptr. EP>>>Как weak_ptr относится к дискуссии? dot>>Как я понял, ты предлагаешь выделить один тред как владелец объекта, т.е. тот, кто держит shared_ptr, а другие треды — просто пользователи объекта, им отдаётся weak_ptr (не голые же указатели передавать?!). EP>Именно голые не владеющие указатели — владелец то переживёт всех. Вполне обычная/нормальная/стандартная практика EP>Smart-pointer'ы прежде всего помогают избавиться от голых владеющих указателей, а не от того что ты подумал.
Бррр... Я уж надеялся, что голые указатели постепенно изничтожаются.
EP>>>>>А например OOM — тоже вполне серьёзно dot>>>>ООМ происходит в яве ровно так же как и в плюсах. Всё то же самое. EP>>>OOM он конечно везде OOM, но причины наступления бывают разные dot>>OOM не кидается в случае если gc есть что освободить. EP>Упёрлись в потолок, GC начинает очень долго освобождать за O(N), отбирая ресурсы у других потоков, общая пропускная способность снижается (забиты каналы памяти, и аллокации происходят медленней), извне приходят всё новые задачи для которых в свою очередь нужна всё новая память, в конце концов либо OOM либо DoS.
Это же сценарий high throughput, а не low latency. В такой ситуации и C++ грохнется — он будет делать ту же работу, просто в рабочих тредах, а на в отдельных gc-тредах как java.
EP>Вот в этом "делаешь" и есть проблема.
EP>Такой Array и другие контейнеры нужно делать для каждого типа данных. У тебя будут FooArray, BarArray, FooPriorityQueue, BarPriorityQueue и т.д. EP>Либо как вариант добавлять лишней динамичности, но от неё будут свои тормоза, причём как размеры заранее не известны.
В LL не так уж и много разных структур. И, как и в С++, и, скорее, всего будут поверх array.
dot>>Да, выглядит некрасиво, но обычно составляет <0.1% кода и сложностей никаких не доставляет. EP>Это одна из главных причин тормозов в языках с превалирующей pointer semantics. Положил класс с несколькими полями-объектами в массив — уже на ровном месте выросло целое дерево индерекций и аллокаций.
В C++ можно тоже кучу главных причин тормозов придумать. Скажем, передача by-value. Непонятно только к чему это. Да, разные инструменты — разные способы решения задач.
dot>>Почему-то я уверен, что "трансформацию реализовывал в библиотечном виде" будет выглядеть гораздо хуже и иметь довольно нетривиальный код. EP>Нет, не хуже, также как и обычный вариант. В реализации — да, код не самый простой, но она пишется один раз. EP>Да и это же Array of Structures, нужно не так часто. Речь же про то, что в Java же нет самых обычных структур — для быстрого кода это супер-критично, именно поэтому и нарезают вручную.
Критически быстрого кода не так много. А значит "нужно не так часто".
EP>>>Понимать как работает железо обязательно нужно. Также нужно понимать как отображаются конструкции языка в железо — и вот с этим у Java проблемы, для быстрого кода приходится отказываться даже от элементарных абстракций и городить low-level код, который даже ниже уровень чем то что есть в языке C. dot>>Да нет каких-то сверх-проблем. Да, нужно писать код определённым образом, реализовывать определённые решения, но это верно для любого оптимизируемого кода на любом языке. Java в этом плане ничуть ни лучше, ничуть не хуже, чем C++. EP>Хуже, намного. Разве пример со структурами тебя не убедил? — это реально уровень ниже чем C, на ровном месте. Так это только один аспект. EP>Быстрый код на C++ можно писать на высоком уровне абстракции — не нужно отказываться ни от замыканий, ни от классов, ни от ФВП и полиморфизма — и при этом он будет давать точно такое же (либо практически такое же) быстродействие как и такой же код написанный на низком уровне вручную — в этом одна из главных фишек C++.
Тут не фичи и уровни абстракции, а хранение и передача данных главное. И там и там об этом надо заботиться. В Яве — не создавать лишних индирекций, в плюса — не делать лишних копий и аккуратно заботиться о владении. Ведь тоже ничего хорошего в том, когда все эти уровни абстракции только и делают, что решают проблемы владения, тогда как в яве оно само, из коробки.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, Evgeny.Panasyuk, Вы писали:
dot>>>>И нифига ненаверифицируешь. EP>>>Старый cast легко отлавливается компилятором, например опция GCC -Werror-old-style-cast dot>>Ну пусть будет reinterpret_cast<Obj *>(obj) какая разница-то? EP>1. reinterpret_cast не снимает константность, мы же о ней говорим?
С void* не снимает?
EP>2. ловится тем же grep'ом
Ну поймали. Для какой-то там 3rd party C библиотеки — оно необходимо. Дальше что?
dot>>А то я скажу, что "gc можно отключить в java" если использовать библиотеки с off-heap. EP>Так ведь так и делают, работают против языка, убегают от GC, потому что он доставляет вполне конкретные проблемы.
И что? Отстутсвие gc тоже доставляет вполне конкретные проблемы, и, кстати, на порядки чаще.
EP>В случае же с boost::thread и т.п. — наоборот работа вместе с языком, а не вопреки ему — std::thread вошёл в стандарт практически в таком же виде, каком он и так был де-факто в библиотеках C++98.
DirectBuffer тоже вошел давно.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>>>Элементарно. Её может расстрелять сторонняя native библиотека, причём даже не из-за бага в самой библиотеке, а потому что Java код нарушил предусловия. Или например может расстрелять свой же Runtime — гарантии нет EP>>>Это аргумент примерно того же порядка что и "OOM везде можно получить" в ответ на описание конкретного use-case'а. dot>>Ты описал юзкейс когда память освобождается медленнее чем потребляется. EP>Причём это происходит по вине самого GC.
Ну подкрути параметры чуток, не проблема.
dot>>Не понимаю каким образом ты избежишь ООМ в таком случае в плюсах? EP>Нет линейной зависимости времени очистки от количества живых объектов. В случае же GC, на одной и той же скорости входящего потока он может либо успевать очищать, либо нет — и это сильно зависит от текущего количества живых объектов.
Если ты в С++ заведёшь очередь для очистки — столкнёшься ровно с той же проблемой. Не вижу разницы.
dot>>Если ты имеешь в виду, что gc выделенного времени не хватило чтобы освободить память, то jvm всегда даёт шанс gc прежде чем бросить ООМ исключение. Да, будет latency spike, но не ООМ. Но это бага конфигурации, исправляется. EP>Так в это время (пока JVM даёт шанс) будут накапливаться всё новые и новые запросы, требующие всё новую и новую память. Это либо OOM либо DoS, а не просто spike.
Это значит, что тупо не хватает ресурсов CPU, в этом случае загнётся всё.
dot>>>>Время чего? Вот у тебя dot>>>>
dot>>>>smartPtr.release(); // упс, заняло 300ms, хотя обычно занимает 3us. Нам не повезло оказаться последним юзером объекта и граф объектов оказался больше обычного.
dot>>>>
EP>>>Не обязательно удалять весь граф сразу, можно по одному узлу, граф-остаток ставить в очередь. dot>>А откуда ты знаешь какой там граф? В данном участке кода ты видишь только "smartPtr". Тебе придётся понимать структуру графа, размеры узлов, етс... EP>Зачем?
Определить граф-остаток.
dot>>>>Как выстоить в очередь граф объектов? EP>>>Например в деструкторе smart-pointer'а не сразу удалять, а ставить в очередь. dot>>Если много мелких объектов — очереди поплохеет, будет хороший такой contention point. EP>Очередь может быть thread local.
И кто из этой очереди будет обрабатывать элементы? Сам thread — не может отвлекаться, он LL, в любую наносекунду может прийти новый запрос.
dot>>>>GC в Java это целый комплекс алгоритмов с тучей настроек. Задача — освобождать память от unreachable объектов, а не просто "отличить". EP>>>А ещё он внутри делает сложение целых чисел. Из этого не следует что сложение целых чисел это "переизобретание современного GC". dot>>Ты задачу GC как-то странно определил. Не отличает он, а освобождает. Отличить — подзадача. EP>В любом случае, ты же говоришь что если делать отложенное очищение, то получаем GC. А если делать сразу почему тогда не GC? А если тоже считаешь что GC, зачем тогда вообще выделять отдельно случай с отложенным очищением?
Это тоже подзадача GC — решать сразу или отложить.
EP>>>Возможен. Заводится отдельная GC Heap, все указатели на элементы внутри этой кучи заворачиваются в gc_ptr<T>. EP>>>Отличать root от не root можно разными способами. Например если сам объект-указатель типа gc_ptr находится не в этой куче — то это root. EP>>>AFAIR, нечто подобное используется в SpiderMonkey. dot>>Я не понимаю чем "написать либу которая делает gc" и "написать jvm которая делает gc". Так хоть можно сказать, что и в маш-кодах gc есть. EP>Разница в том, что написанная библиотека используется внутри самого host-языка. То есть эти gc_ptr — они используется не внутри какой-то виртуальной среды созданной библиотекой, а внутри вызывающего host-языка.
Так и деструкторы и прочие С++ фишки можно реализовать в java, см. offheap. Выделяешь память как блок внутри DirectBuffer, вместо использования оператора new. Непонятно только к чему всё это.
dot>>>>и обычно минимально влияя на основные потоки. EP>>>Memory throughput не бесконечная, более того — часто является bottleneck'ом. GC во время обхода интенсивно использует память, сужая этот bottleneck. dot>>Пусть, для LL критичной системы gc будет работать на другом ядре, используя другой банк памяти (опять же, заметь, — ничего java specific). EP>Какой другой банк памяти? Ему нужно обходить именно ту память, с которой работают полезные потоки, тем самым путаясь у них под ногами.
Хм, не знаю. Может быть, но пока не доводилось с подобными проблемами сталкиваться. В Memory throughput пока не упирались. LL обычно пишется garbage-free, и поэтому нагрузка на gc минимальна. В high throughput — да, возможно.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
dot>>>>>Мало того, тот кому не повезло освобождать ссылку последним — не придётся тратить ВНЕЗАПНО время на освобождение, EP>>>>Пусть просто поставит в очередь, делов-то dot>>>Поставит что? Сразу весь развесистый граф? А если надо только часть освободить? Ставить каждый самый мелкий объект? А очереди не поплохеет? EP>>Не каждый объект, а те которые не успеваем освободить. dot>А как мы будем выяснять — успеем или не успеем?
Замерами — например смотрим максимальное/среднее/etc время очистки одного узла. Причём тот же finalize есть и Java.
Если же речь идёт о hard real time — то там применяются совершенно другие приёмы.
dot>>>>>На java память ресурс другого типа. "Освобождать память" там нельзя. EP>>>>А я поэтому и сказал конкретно "ресурс", а не просто "объект". Да и память не ресурс только если она не ограниченна — упрёшься в предел, получишь удар по latency, на который постоянно ссылаешься. dot>>>В low latency единственный ресурс обычно память. EP>>Сильное утверждение. Да и это проблема ко всему относится, а не только к low latency. dot>Что-то не понял. Которая проблема?
Задача работы с ресурсами.
dot>>>>>А для ресурсов в общем случае — наследники java.lang.ref.Reference. EP>>>>Каким образом они обеспечат prompt finalization? dot>>>А надо? EP>>Надо, это задача. dot>Какая именно задача? Ты не путаешь задачу со способом решения?
Задача — своевременное освобождение ресурсов.
dot>>>А зачем вообще ресурсы обязательно освобождать из финалайзеров? EP>>Освобождай откуда угодно, но покажи как это реализуется в Java. dot>
Про эти костыли я в курсе, но ты покажи как будешь их применять в поставленной задаче. Или например как бороться с транзитивностью "быть ресурсом" при агрегировании.
dot>>>Я не понял какую задачу ты описываешь. EP>>Ту же самую, с потоками, при завершении последнего нужно освободить ресурс. dot>Эээ.. Попробую сформулировать. Открыть файл, раздать открытый файл пачке тредов, которые могут так же кидаться файлами с другими тредами и закрыть, когда последний тред его обработает. Так? Собственно решение будет аналогично С++, взять какой-нибудь подходящий класс из java.lang.concurrent.* и реализовать контроль пользователей ресурса.
Как именно? Как ресурс будет передаваться в потоки? Кто и как будет решать что нужно удалить?
dot>Ещё раз, в java есть только один специально обрабатываемый ресурс — память. Не надо натягивать gc на контроль любых ресурсов, он только для памяти.
А я не натягиваю. Я предлагаю тебе решить, или хотя бы описать решение любым способом.
dot>Я понимаю откуда растёт это заблуждение. Деструктор в С++ может быть использован как для памяти, так и для любых других ресурсов. Не надо переносить это понимание в java. В java gc — только для памяти. Другие ресурсы — с помощью try-with-resources контролируются.
Про заблуждение это ты придумал. Я прекрасно знаю об этих всех костылях а-ля with/using/try-with-resources.
dot>>>>>Ну да... Только, как мне кажется. эти схемы гораздо проще если есть gc. EP>>>>При GC чуть проще реализация lockfree структур данных, за счёт ABA, но при этом сами GC в большинстве своём не lockfree (lockfree GC видел только в статьях) — то есть тут уже большой терминологический вопрос, остаётся ли структура данных lockfree при не non-lockfree GC dot>>>Если локи расставляются сами компилятором и лочится на предсказуемое время — почему бы и нет. EP>>Потому что lock'и это не lockfree, принципиально. Смотри определение. Lockfree это прежде всего некоторые гарантии, а не например скорость — скорость вообще может быть меньше. EP>>Да и кто сказал что время предсказуемо? Например GC заснул захватив lock, остальные ждут. Тут желательно хотя бы obstruction free dot>lockfree это гарантии на уровне кода, а что там делает окружение — не важно. Скажем, если операционка вытесняет твой поток — по сути она лочит его — исполнение приостанавливается. А ещё и CPU может заснуть, скажем для экономии энергии или для регуляции тепловыделения. И что? lockfree и на C++ невозможен?
Прочитай определение lock-free.
dot>Я тебе сразу сказал "Когда ответишь на эти вопросы и многие другие, то переизобретёшь современный gc."
Здравствуйте, ·, Вы писали:
dot>>>Если VM оптимизатор видит, что объект используется только в одном месте, он переносит ссылку на стек, т.е. по сути выводит unique_ptr. EP>>И не в покер, а в преферанс. И не выиграл, а проиграл. EP>>И не ссылку, а сам объект. И не unique_ptr, а просто стэковый объект. dot>Перенос объекта на стек это другая оптимизация. Может делаться только для маленьких оъбектов. Если у тебя выделяется 100мб массив и EA покажет, что ссылка на массив не убегает за пределы, то при выходе из стека объект грохнется. Т.е. по сути тот же unique_ptr.
То есть имелось в виду scoped_ptr — более ограниченная версия unique_ptr. Например unique_ptr можно возвращать из функции.
И то, если брать случай с массивом как ты сказал — то тут не нужен никакой *_ptr, достаточно просто vector:
{
vector<Widget> values(N);
foo();
// ...
}
dot>массив не убегает за пределы, то при выходе из стека объект грохнется
Каким образом грохнется? Речь только про некомпактифицируемые кучи?
dot>>>>>shared_ptr у треда-владельца, а "зависимые" — имеют weak_ptr. EP>>>>Как weak_ptr относится к дискуссии? dot>>>Как я понял, ты предлагаешь выделить один тред как владелец объекта, т.е. тот, кто держит shared_ptr, а другие треды — просто пользователи объекта, им отдаётся weak_ptr (не голые же указатели передавать?!). EP>>Именно голые не владеющие указатели — владелец то переживёт всех. Вполне обычная/нормальная/стандартная практика EP>>Smart-pointer'ы прежде всего помогают избавиться от голых владеющих указателей, а не от того что ты подумал. dot>Бррр... Я уж надеялся, что голые указатели постепенно изничтожаются.
Ты что, они же есть в реальности данной нам в ощущениях железом. Это же например самый быстрый способ указать на конкретный элемент массива, или передать куда-нибудь его часть.
EP>>>>>>А например OOM — тоже вполне серьёзно dot>>>>>ООМ происходит в яве ровно так же как и в плюсах. Всё то же самое. EP>>>>OOM он конечно везде OOM, но причины наступления бывают разные dot>>>OOM не кидается в случае если gc есть что освободить. EP>>Упёрлись в потолок, GC начинает очень долго освобождать за O(N), отбирая ресурсы у других потоков, общая пропускная способность снижается (забиты каналы памяти, и аллокации происходят медленней), извне приходят всё новые задачи для которых в свою очередь нужна всё новая память, в конце концов либо OOM либо DoS. dot>Это же сценарий high throughput, а не low latency. В такой ситуации и C++ грохнется — он будет делать ту же работу, просто в рабочих тредах, а на в отдельных gc-тредах как java.
Не грохнется — у него нет зависимости O(N) от количества живых объектов.
EP>>Вот в этом "делаешь" и есть проблема. EP>>Такой Array и другие контейнеры нужно делать для каждого типа данных. У тебя будут FooArray, BarArray, FooPriorityQueue, BarPriorityQueue и т.д. EP>>Либо как вариант добавлять лишней динамичности, но от неё будут свои тормоза, причём как размеры заранее не известны. dot>В LL не так уж и много разных структур.
Ты постоянно говоришь о каком-то одном use-case'ы.
Даже если и мало — всё равно придётся опускаться на очень низкий уровень, исключительно из-за самого языка.
dot>И, как и в С++, и, скорее, всего будут поверх array.
Это ты о чём?
Например на C++ есть выгода от структур (в смысле хранения по значению) даже для вещей типа сбалансированных деревьев — так как уменьшает количество индерекций — само значение хранится в узле, а не указатель на значение.
dot>>>Да, выглядит некрасиво, но обычно составляет <0.1% кода и сложностей никаких не доставляет. EP>>Это одна из главных причин тормозов в языках с превалирующей pointer semantics. Положил класс с несколькими полями-объектами в массив — уже на ровном месте выросло целое дерево индерекций и аллокаций. dot>В C++ можно тоже кучу главных причин тормозов придумать. Скажем, передача by-value. Непонятно только к чему это.
Так тут есть простой выбор — by-value или by-reference. Это совершенно не тоже самое что и засучив рукава нарезать байт-буфера на структуры
dot>Да, разные инструменты — разные способы решения задач.
Тут не спорю
dot>>>Почему-то я уверен, что "трансформацию реализовывал в библиотечном виде" будет выглядеть гораздо хуже и иметь довольно нетривиальный код. EP>>Нет, не хуже, также как и обычный вариант. В реализации — да, код не самый простой, но она пишется один раз. EP>>Да и это же Array of Structures, нужно не так часто. Речь же про то, что в Java же нет самых обычных структур — для быстрого кода это супер-критично, именно поэтому и нарезают вручную. dot>Критически быстрого кода не так много. А значит "нужно не так часто".
Мы же быстрый код обсуждаем?
EP>>>>Понимать как работает железо обязательно нужно. Также нужно понимать как отображаются конструкции языка в железо — и вот с этим у Java проблемы, для быстрого кода приходится отказываться даже от элементарных абстракций и городить low-level код, который даже ниже уровень чем то что есть в языке C. dot>>>Да нет каких-то сверх-проблем. Да, нужно писать код определённым образом, реализовывать определённые решения, но это верно для любого оптимизируемого кода на любом языке. Java в этом плане ничуть ни лучше, ничуть не хуже, чем C++. EP>>Хуже, намного. Разве пример со структурами тебя не убедил? — это реально уровень ниже чем C, на ровном месте. Так это только один аспект. EP>>Быстрый код на C++ можно писать на высоком уровне абстракции — не нужно отказываться ни от замыканий, ни от классов, ни от ФВП и полиморфизма — и при этом он будет давать точно такое же (либо практически такое же) быстродействие как и такой же код написанный на низком уровне вручную — в этом одна из главных фишек C++. dot>Тут не фичи и уровни абстракции, а хранение и передача данных главное. И там и там об этом надо заботиться. В Яве — не создавать лишних индирекций, в плюса — не делать лишних копий и аккуратно заботиться о владении. Ведь тоже ничего хорошего в том, когда все эти уровни абстракции только и делают, что решают проблемы владения, тогда как в яве оно само, из коробки.
Это уже передёргивание. Да, работу с памятью GC упрощают (при этом не гарантируя отсутствие утечек). Да, на C++ нужно думать/помнить о владении (это не означает что каждый new на Java превращается в *_ptr).
Нет, уровни абстракции о которых я говорю решают далеко не только проблемы владения — они позволяют писать высокоуровневый И быстрый код.
Здравствуйте, ·, Вы писали:
dot>>>>>И нифига ненаверифицируешь. EP>>>>Старый cast легко отлавливается компилятором, например опция GCC -Werror-old-style-cast dot>>>Ну пусть будет reinterpret_cast<Obj *>(obj) какая разница-то? EP>>1. reinterpret_cast не снимает константность, мы же о ней говорим? dot>С void* не снимает?
reinterpret_cast не снимает const с const void *p.
EP>>2. ловится тем же grep'ом dot>Ну поймали. Для какой-то там 3rd party C библиотеки — оно необходимо. Дальше что?
Явно разрешаем несколько таких unsafe мест. И?
EP>>В случае же с boost::thread и т.п. — наоборот работа вместе с языком, а не вопреки ему — std::thread вошёл в стандарт практически в таком же виде, каком он и так был де-факто в библиотеках C++98. dot>DirectBuffer тоже вошел давно.
Так смысл-то не то что boost::thread есть давно, а в том что он удобен для своей задачи. Если же смотреть на эти все *Buffer для эмуляции структур — то очевидно что сами структуры удобнее на порядки
Здравствуйте, ·, Вы писали:
EP>>Причём это происходит по вине самого GC. dot>Ну подкрути параметры чуток, не проблема.
Это уберёт линейную сложность?
dot>>>Не понимаю каким образом ты избежишь ООМ в таком случае в плюсах? EP>>Нет линейной зависимости времени очистки от количества живых объектов. В случае же GC, на одной и той же скорости входящего потока он может либо успевать очищать, либо нет — и это сильно зависит от текущего количества живых объектов. dot>Если ты в С++ заведёшь очередь для очистки — столкнёшься ровно с той же проблемой. Не вижу разницы.
В очереди объекты которые уже готовы для очистки. А вот сколько там живых reachable объектов — не важно, пусть хоть десять миллиардов.
dot>Это значит, что тупо не хватает ресурсов CPU, в этом случае загнётся всё.
Так не хватает-то их из-за линейной сложности GC.
EP>>Зачем? dot>Определить граф-остаток.
Зачем его определять? Что это даст?
Пока не превысим бюджет времени — удаляем сами, как только времени осталось меньше чем требует max объект — ставим остаток в очередь.
EP>>Очередь может быть thread local. dot>И кто из этой очереди будет обрабатывать элементы? Сам thread — не может отвлекаться, он LL, в любую наносекунду может прийти новый запрос.
От задачи зависит, может и сам thread. А может и отдельный thread, при этом contention с другими потоками всё равно не будет — так как очередь SPSC.
dot>Это тоже подзадача GC — решать сразу или отложить.
А ещё в подзадачах GC есть сложение целых.
EP>>Разница в том, что написанная библиотека используется внутри самого host-языка. То есть эти gc_ptr — они используется не внутри какой-то виртуальной среды созданной библиотекой, а внутри вызывающего host-языка. dot>Так и деструкторы и прочие С++ фишки можно реализовать в java,
Каким образом ты реализуешь деструкторы? Какое будет использование? Каким образом реализуешь например Expression Templates и прочие compile-time EDSL?
dot>см. offheap. Выделяешь память как блок внутри DirectBuffer, вместо использования оператора new. Непонятно только к чему всё это.
Ну так этот блок придётся вручную нарезать на структуры, о чём я выше и говорил.
Здравствуйте, ·, Вы писали:
PM>>>> Короче, сплошной <троллейбус из буханки хлеба.jpeg>
·>Война была, да и до сих пор ведётся не с java, а с архитектурой и железом. 90% тех решений подходит и для С++.
Только цена усилий по улучшению быстродействия в проекте на C++ гораздо меньше. Понадобилось попадание в кэш-линию и исключение false sharing — выровняли структуру. Не нужно переключение контекста — привязали поток к конкретному ядру. SIMD, вычисления на GPU, сетевой стек в user space. В Java с этим будут трудности. И героически преодолевать их — см. выделенное.
PM>>Я почитал ваши сообщения в ветке. Ещё одна иллюстрация, что люди не из мира C++ продолжают верить в мифы 15-20 летней давности. Авторы LMAX скорее всего тоже подумали: "Писать такое на C++... неее... проще застрелиться" и взяли хорошо известный им и широко распространённый инструмент. Хорошо, что при этом они не застрелились ·>На плюсах есть куски или нативные либы, но как-то постепенно перетекает всё в java. Ибо работает так же, а добавляется куча преимуществ (см ролик http://rsdn.ru/forum/philosophy/6205646.1
) ·>Как в одно время был процесс переползания с ассемблеров на фортран, на С, на С++, теперь вот java. Конечно, на arduino яву не запустишь, но нишу LL она уверенно отвоёвывает.
Да, да, "write once, run anywhere", Java завоюет мир... Когда-то читал про такое, лет 20 назад. По-моему ниша Java всё та же — корпоративные и банковские приложения. Может андроид слегка добавил, пока разработчики не выяснили, что писать мобильные приложения выгоднее с общим ядром на C++ и пользовательским интерфейсом под конкретную платформу.
Это издержки портирования с другого языка. Таким же образом из Java мира перевели jUnit. И где тот cppUnit? В новых проектах на C++ теперь обычно встречаются Catch, Boost.Test, Google test потому что они используют идиомы C++
Здравствуйте, ·, Вы писали:
·>И с тех пор ты никогда в жизни не расстрелял память или не видел, когда вполне дисциплинированый дев расстреливал? ·>В ядре линуха такие баги находили (а там, видимо бардак и диверсанты).
А, я забыл, программы на жабе и шарпе никогда на глючат и в них не бывает багов.
·>Вот поэтому и не нужно считать константным, а тупо использовать иммутабельный тип (что при наличии деструкторов в языке сделать невозможно).
Всё смешалось в кучу, люди, кони. Как наличие деструкторов мешает иммутабельным типам?
Расскажи, в жабошарпах можно ли кастовать мутабельный указатель в немутабельный?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, T4r4sB, Вы писали:
TB>·>И с тех пор ты никогда в жизни не расстрелял память или не видел, когда вполне дисциплинированый дев расстреливал? TB>·>В ядре линуха такие баги находили (а там, видимо бардак и диверсанты). TB>А, я забыл, программы на жабе и шарпе никогда на глючат и в них не бывает багов.
Ты вроде обещал, что будет дисциплина — проблемы не будет. Однако, чуда не вышло.
TB>·>Вот поэтому и не нужно считать константным, а тупо использовать иммутабельный тип (что при наличии деструкторов в языке сделать невозможно). TB>Всё смешалось в кучу, люди, кони. Как наличие деструкторов мешает иммутабельным типам?
Что наличие ссылки на иммутабельный объект не даёт гарантии, что его поведение не поменяется.
TB>Расскажи, в жабошарпах можно ли кастовать мутабельный указатель в немутабельный?
В смысле присвоить новое значение к final полю/переменной? Нет, конечно. Нельзя.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
·>Ты вроде обещал, что будет дисциплина — проблемы не будет. Однако, чуда не вышло.
Ты вроде обещал, что будет жаба — проблемы не будет. Однако, чуда не вышло.
Ещё раз: я не спорю с тем, что в крестах напортачить проще и требования к программистам выше. Ты сейчас типа пытаешься доказать мне, что жаба — серебрянная пуля?
·>Что наличие ссылки на иммутабельный объект не даёт гарантии, что его поведение не поменяется.
Я тупой, так что давай выкладывай все звенья логической цепи.
TB>>Расскажи, в жабошарпах можно ли кастовать мутабельный указатель в немутабельный? ·>В смысле присвоить новое значение к final полю/переменной? Нет, конечно. Нельзя.
Ааа, иммутабельный класс — это класс, в котором все поля final?
Можно ли в С++ можно всем полям написать const? Нет, конечно. Нельзя. (Сарказм).
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, PM, Вы писали:
PM>>>>> Короче, сплошной <троллейбус из буханки хлеба.jpeg> PM>·>Война была, да и до сих пор ведётся не с java, а с архитектурой и железом. 90% тех решений подходит и для С++. PM>Только цена усилий по улучшению быстродействия в проекте на C++ гораздо меньше.
Не правда.
PM> Понадобилось попадание в кэш-линию и исключение false sharing — выровняли структуру. Не нужно переключение контекста — привязали поток к конкретному ядру. PM> SIMD, вычисления на GPU, сетевой стек в user space. В Java с этим будут трудности. И героически преодолевать их — см. выделенное.
И что из этого невозможно сделать ява?
А какие именно трудности? Можно по пунктам?
SIMD инструкции генерятся JIT (хотя интересно услышать о их полезности в low latency/finance).
сетевой стек — это этот что-ли? http://docs.oracle.com/javase/tutorial/sdp/sockets/
GPU — тоже непонятна полезность, да и тоже куча всего http://stackoverflow.com/questions/22866901/using-java-with-nvidia-gpus-cuda
С остальным вообще не ясно что за проблемы, не рокет сайнс.
PM>·>На плюсах есть куски или нативные либы, но как-то постепенно перетекает всё в java. Ибо работает так же, а добавляется куча преимуществ (см ролик http://rsdn.ru/forum/philosophy/6205646.1
) PM>·>Как в одно время был процесс переползания с ассемблеров на фортран, на С, на С++, теперь вот java. Конечно, на arduino яву не запустишь, но нишу LL она уверенно отвоёвывает. PM>Да, да, "write once, run anywhere", Java завоюет мир... Когда-то читал про такое, лет 20 назад. По-моему ниша Java всё та же — корпоративные и банковские приложения. Может андроид слегка добавил, пока разработчики не выяснили, что писать мобильные приложения выгоднее с общим ядром на C++ и пользовательским интерфейсом под конкретную платформу.
Я и не утверждало всём мире. Мир не завоевала, но LL нишу занимает прочно.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, T4r4sB, Вы писали:
TB>·>Ты вроде обещал, что будет дисциплина — проблемы не будет. Однако, чуда не вышло.
TB>Ты вроде обещал, что будет жаба — проблемы не будет. Однако, чуда не вышло.
Так в яве и нет проблемы битых указателей. Чудо, однако. А то что нативный код может поднасрать, это не аргумент. А ещё java кнопку reset не может запретить нажать, и что?
TB>Ещё раз: я не спорю с тем, что в крестах напортачить проще и требования к программистам выше. Ты сейчас типа пытаешься доказать мне, что жаба — серебрянная пуля?
Нет, что некоторые классы проблем решает.
TB>·>Что наличие ссылки на иммутабельный объект не даёт гарантии, что его поведение не поменяется. TB>Я тупой, так что давай выкладывай все звенья логической цепи.
Меняешь чуток код и вдруг вылазишь за время жизни объекта. Упс, битый указатель.
TB>>>Расскажи, в жабошарпах можно ли кастовать мутабельный указатель в немутабельный? TB>·>В смысле присвоить новое значение к final полю/переменной? Нет, конечно. Нельзя. TB>Ааа, иммутабельный класс — это класс, в котором все поля final? TB>Можно ли в С++ можно всем полям написать const? Нет, конечно. Нельзя. (Сарказм).
Можно, конечно. Но деструктор запретить-то нельзя.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
·>Так в яве и нет проблемы битых указателей. Чудо, однако. А то что нативный код может поднасрать, это не аргумент. А ещё java кнопку reset не может запретить нажать, и что?
Ты путаешь С++ и чистую сишку. В С++ при правильном использовании тоже нет битых указателей.
·>Меняешь чуток код и вдруг вылазишь за время жизни объекта. Упс, битый указатель.
Как можно грохнуть объект, пока он ещё кем-то используется? По-моему, это косяк программиста куда более серьёзный, чем просто какой-то битый указатель.
·>Можно, конечно. Но деструктор запретить-то нельзя.
...но ГЦ и финализатор запретить нельзя...
(я хз, к чему это, просто разговор поддержать)
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, T4r4sB, Вы писали:
TB>·>Так в яве и нет проблемы битых указателей. Чудо, однако. А то что нативный код может поднасрать, это не аргумент. А ещё java кнопку reset не может запретить нажать, и что? TB>Ты путаешь С++ и чистую сишку. В С++ при правильном использовании тоже нет битых указателей.
Тут в топике мне предлагают использовать голые указатели. Это правильное использование? А cyclic references тоже правильное?
TB>·>Меняешь чуток код и вдруг вылазишь за время жизни объекта. Упс, битый указатель. TB>Как можно грохнуть объект, пока он ещё кем-то используется? По-моему, это косяк программиста куда более серьёзный, чем просто какой-то битый указатель.
В С++ — запросто. В java — никак.
TB>·>Можно, конечно. Но деструктор запретить-то нельзя. TB>...но ГЦ и финализатор запретить нельзя... TB>(я хз, к чему это, просто разговор поддержать)
Конечно нельзя. Но обратиться к объекту, попавшему ГЦ на растерзание — тоже нельзя.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>>>Врёшь же. Я конкретно сказал что контроль над временем ортогонален "как на Си". I>>Это просто твоё мнение, ничем не аргументированое.
EP>Это аргумент. Ты можешь быть согласен с ним или нет.
А противоположная формулировка, хочешь ты или нет, тоже аргумент или как ?
А если она из одного слова, как отсылка к контексту ?
Опаньки !
EP>Задача была сделать подстраховку, я сказал что такая подстраховка не реализуема на C, ты сказал что "реализуема, только иначе"
У твоей подстраховки один побочный эффект — время выполнения может быть недетерминированым.
EP>То есть ты не понимаешь в чём тут отличие у C++11
Ты утомляешь передёргиваниями.
I>>Твоя "подстраховка", требует ресурсов. Каскадная очистка — часть этой самой подстраховки. Вместо явной логики "вычислить и освободить явно" выбираем неявную "пусть деструкторы срабатывают каскадом по цепочке, авось пронесёт"
EP>Ещё раз, эта каскадная очистка была бы и без ref-counting. Understand?
Я же сказал, что каскадная очистка это один из возможных вариантов реализации. Тебе её удобно делать деструкторами. Отсюда ясно, что хрен его знает, какое будет время работы.
Здравствуйте, Ikemefula, Вы писали:
EP>>>>Врёшь же. Я конкретно сказал что контроль над временем ортогонален "как на Си". I>>>Это просто твоё мнение, ничем не аргументированое. EP>>Это аргумент. Ты можешь быть согласен с ним или нет. I>А противоположная формулировка, хочешь ты или нет, тоже аргумент или как ?
А смысл просто так повторять противоположную формулировку? Скажи что не согласен потому-то и тому-то, или хотя бы попроси разъяснения — зачем кирпичом прикидываться?
I>А если она из одного слова, как отсылка к контексту ? I>Опаньки !
На C можно писать как с "контролем над временем", так и без него — это ортогональное свойство. Точно также и для C++. Поэтому контроль над временем ортогонален "как на Си".
Вот есть бы сказал что "как на блаб", при этом блаб бы использовался исключительно для задач контролем над временем — был бы другой разговор.
EP>>Задача была сделать подстраховку, я сказал что такая подстраховка не реализуема на C, ты сказал что "реализуема, только иначе" I>У твоей подстраховки один побочный эффект — время выполнения может быть недетерминированым.
Эта подстраховка никак не влияет на порядок вызова деструкторов, он остаётся таким же как было бы и без неё.
EP>>То есть ты не понимаешь в чём тут отличие у C++11 I>Ты утомляешь передёргиваниями.
Я причём тут передёргивание? Ты не понимаешь важный для дискуссии аспект. В C++11 есть нововведение позволяющее существенно снизить количество ref inc/dec.
I>>>Твоя "подстраховка", требует ресурсов. Каскадная очистка — часть этой самой подстраховки. Вместо явной логики "вычислить и освободить явно" выбираем неявную "пусть деструкторы срабатывают каскадом по цепочке, авось пронесёт" EP>>Ещё раз, эта каскадная очистка была бы и без ref-counting. Understand? I>Я же сказал, что каскадная очистка это один из возможных вариантов реализации. Тебе её удобно делать деструкторами. Отсюда ясно, что хрен его знает, какое будет время работы.
Нет, ты потерял контекст. Мы сейчас рассматриваем случай где использование ref-counting избыточно, то есть не продиктовано самой задачей, как в случае с разделяемым владением(а такие задачи сами по себе редки). В этом случае ref-counting никак не влияет на порядок вызова деструкторов.