Давно не программировал, поэтому если встретятся фактические ошибки, делающие неверной цепь рассуждений, просьба просто указать на них. Если это трюизмы (== баян, если в словарь лазить лень), то причина в том же.
Насколько мне известно, память в языках типа Явы или Шарпа — не ресурс. Вернее, ресурс, но управляет им некая внешняя по отношению к программе штуковина — рантайм или виртуальная машина, или еще какой контейнер.
У программистов на плюсах был излюбленный прием — использовать пару конструктор-деструктор для контроля за выходом из блока кода. Например, CWaitCursor() делал запрос к API на отрисовку песочных часов, а ~CWaitCursor() вертал все в зад. Соответственно, можно было разместить на стеке анонимный объект в любом блоке, который управлял курсором автоматически и этот трюк был эксепшено-безопасным, что немаловажно. Конструкции finally не требовалось.
Теперь объекты размещаются в куче, но время их уничтожения недетерминировано.
Почему не ввести вместо using на такой случай специальный тип — стековый класс? Это ведь не потребует усложнения синтаксиса. Просто у структуры появится деструктор с детерминированным временем вызова.
Здравствуйте, PC Car, Вы писали:
PC>Почему не ввести вместо using на такой случай специальный тип — стековый класс? Это ведь не потребует усложнения синтаксиса. Просто у структуры появится деструктор с детерминированным временем вызова.
Вообще насчет баяна ты угадал
То есть ты предлагаешь создать типы которые можно располагать только на стеке? И ты думаешь это полетит (в смысле покроет потребности)?
Оставим в покое песочные часы и возьмем SomeConnection к примеру.
Хранить ее только на стеке? Спасибо не надо...
Разрешим хранить в куче? Привет using...
Здравствуйте, PC Car, Вы писали:
PC>Почему не ввести вместо using на такой случай специальный тип — стековый класс? Это ведь не потребует усложнения синтаксиса. Просто у структуры появится деструктор с детерминированным временем вызова.
В C++/CLI так и сделано. Жить от это особо лучше не стало. По крайней это не компенсировало отсуствия в C++/CLI других полезных свойств Шарпа.
На самом деле после некоторого опыта использования управляемых языков понимашь, что страхи плюсовиков (коим я являлся до перехода на управляемые среды) сильно надуманы. 99% контроля ресурсов — это контроль памяти. А когда память не нужно пасти, то остальное можно хоть руками контролировать. В общем using-а за глаза хватает.
Ну, а стековый объект все равно не всегда поможет. Ведь если время жизни объекта не совпадает с временем проведенным в процедуре, то и контролировать его так не выйдет.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Сборщик мусора и размещение объектов в стеке
Здравствуйте, GarryIV, Вы писали:
GIV>Оставим в покое песочные часы и возьмем SomeConnection к примеру.
GIV>Хранить ее только на стеке? Спасибо не надо... GIV>Разрешим хранить в куче? Привет using...
Почему бы не разрешить хранить только на стеке? А если всё же "Спасибо не надо... ", то разрешаешь хранить на стеке объект, который в конструкторе получает соединение из пула, а в деструкторе возвращает в пул.
В отношении Java 6 нечто подобное (оптимизация под названием Escape-анализ) уже реальность:
Стековая аллокация
C++ предлагает программистам на выбор аллокацию объектов в массиве или в стеке. Стековая аллокация является эффективной: аллокация недорога, затраты на деаллокацию почти равны нулю, а язык помогает демаркировать жизненные циклы объекта, снижая риск того, что объект забудут освободить. С другой стороны, в C++ вам нужно быть очень осторожными при публикации или совместном использовании ссылок на стековые объекты, потому что стековые объекты автоматически освобождаются, когда стековый фрейм раскрывается, приводя к появлению неработающих ссылок.
Другим преимуществом стековой аллокации является то, что она гораздо более удобна для кэша. В современных процессорах цена кэш-промахов весьма значительна, следовательно, если язык и рабочий цикл могут помочь вашей программе достичь лучшей локализации данных, то производительность улучшится. Верхушка стека почти всегда "горячая" в кэше, тогда как верхушка массива почти всегда "холодная" (потому что наверняка прошло достаточно времени с тех пор, как использовалась эта память). В результате аллокация объекта в массиве, скорее всего, повлечет за собой больше кэш-промахов, чем аллокация объекта в стеке.
Плохо то, что кэш-промах при аллокации объекта в массиве имеет особенно опасное взаимодействие с памятью. При аллокации памяти из массива содержимое данной памяти является мусором — любые биты, оставшиеся после того, как память использовалась в последний раз. Если вы размещаете блок памяти в массиве, который еще не находится в кэше, при выполнении возможны зависания, пока содержимое данной памяти будет переноситься в кэш. Затем вы немедленно перепишете эти значения, которые вы затратили на то, чтобы перенести в кэш с нулями или другими исходными данными, а это приводит к большим потерям работы памяти. (Некоторые процессоры, такие как Azul's Vega, включают аппаратную поддержку для ускорения аллокации массива).
Escape-анализ
Язык Java не предлагает никакого способа точно расположить объект в стеке, но этот факт не мешает JVM использовать стековую аллокацию, где это уместно. JVM может использовать технологию, именуемую escape-анализ, с помощью которой можно сказать, что определенные объекты удерживаются в одном потоке в течение всего жизненного цикла, а он связан со временем существования данного стекового фрейма. Такие объекты можно безопасно располагать в стеке вместо массива. Что даже лучше для маленьких объектов, JVM может полностью оптимизировать аллокацию и просто поднять поля объекта в списки.
(прим. ред. — далее приводятся примеры с псевдокодом оптимизации)
...
Escape-анализ в Mustang
Escape-анализ является оптимизацией, о которой уже давно говорилось, и наконец-то вот она — текущие сборки Mustang (Java SE 6) могут осуществлять escape-анализ и конвертировать аллокацию массива в стековую аллокацию (или без аллокации) там, где это уместно. Использование escape-анализа для устранения некоторых результатов аллокаций с более быстрым средним временем аллокации, уменьшенным потреблением ОЗУ и меньшим количеством кэш-промахов. Кроме этого, оптимизирование некоторых аллокаций уменьшает давление на сборщик мусора и позволяет реже запускать сборку.
Здравствуйте, PC Car, Вы писали:
PC>Почему не ввести вместо using на такой случай специальный тип — стековый класс? Это ведь не потребует усложнения синтаксиса. Просто у структуры появится деструктор с детерминированным временем вызова.
А ты дальше подумай — что делать, если эта структура будет полем класса, уничтожение которого недетерминировано?
Здравствуйте, VladD2, Вы писали:
VD>На самом деле после некоторого опыта использования управляемых языков понимашь, что страхи плюсовиков (коим я являлся до перехода на управляемые среды) сильно надуманы. 99% контроля ресурсов — это контроль памяти. А когда память не нужно пасти, то остальное можно хоть руками контролировать. В общем using-а за глаза хватает.
Ресурсами, которые контролируются стековым объектом, могут быть не только такие объекты как соединение, файл и т.д.
Техника значительно шире. Например, с помощью стекового объекта может контролироваться временный перевод курсора в "часики", блокировка/разблокировка мьютекса, задержка/возобновление обновления графического элемента управления, резервирование/разрезервирование какого-либо места/счётчика и т.д. и т.д.
Так же техника применяется для обеспечения транзакционности, когда действие, выполняемое в деструкторе объекта, отменяется методом commit(). Например транзакционная вставка в 3 контейнера (всё или ничего):
Если у объекта типа push_back_tx не был вызван метод commit(), то в деструкторе он удаляет из контейнера элемент, который вставил в конструкторе.
Как это будет выглядеть в языке без стековой семантики? Я не видел красивого и *масштабируемого* решения.
Такие приёмы делают разработку не только проще и приятней, но так же, что не менее важно, автоматически обеспечивают надёжность и робустность кода. Если в языке без исключений стековая семантика могла бы являться приятной фичей, то в языке с исключениями стековая семантика — необходимое условие разработки надёжного кода.
VD>Ну, а стековый объект все равно не всегда поможет. Ведь если время жизни объекта не совпадает с временем проведенным в процедуре, то и контролировать его так не выйдет.
Хммм... Такие заявления ставят под сомнение твоё умение программировать на языках со стековой семантикой...
Если время жизни объекта не совпадает с временем проведенным в процедуре, то объект создаётся в динамической памяти, а на стеке создаётся объект, контролирующий время жизни первого объекта:
Здравствуйте, rsn81, Вы писали:
R>Здравствуйте, PC Car, Вы писали:
R>В отношении Java 6 нечто подобное (оптимизация под названием Escape-анализ) уже реальность:[q]Стековая аллокация
LOL
Как сделать хорошо? Вначале сделайте плохо, а потом сделайте как было.
Вначале ввели аллокацию на стеке, потом ручное управление памятью... Осталось только union'ы вернуть
Здравствуйте, remark, Вы писали:
R>LOL R>Как сделать хорошо? Вначале сделайте плохо, а потом сделайте как было. R>Вначале ввели аллокацию на стеке, потом ручное управление памятью... Осталось только union'ы вернуть R>
Иронию не догнал: ручную-детерминированную аллокацию на стеке никто и не обещал, а про ручное управление памятью вообще не понял. Так что чего-то вы не по теме радуетесь.
Re[4]: Сборщик мусора и размещение объектов в стеке
Здравствуйте, rsn81, Вы писали:
R>Здравствуйте, remark, Вы писали:
R>>LOL R>>Как сделать хорошо? Вначале сделайте плохо, а потом сделайте как было. R>>Вначале ввели аллокацию на стеке, потом ручное управление памятью... Осталось только union'ы вернуть R>> R>Иронию не догнал: ручную-детерминированную аллокацию на стеке никто и не обещал, а про ручное управление памятью вообще не понял. Так что чего-то вы не по теме радуетесь.
Ищи по "The Real-Time Specification for Java". Фактически они добавили синхронное освобождение памяти — схема применяемая в современном С++.
Здравствуйте, remark, Вы писали:
R>Ищи по "The Real-Time Specification for Java". Фактически они добавили синхронное освобождение памяти — схема применяемая в современном С++.
Нет. В realtime Java _нет_ синхронного освобождения памяти — это сделать в общем случае чрезвычайно дорого. Для realtime Java гарантируются только верхние границы на время отклика сборщика мусора, ничего более.
Sapienti sat!
Re[2]: Сборщик мусора и размещение объектов в стеке
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, PC Car, Вы писали:
PC>>Почему не ввести вместо using на такой случай специальный тип — стековый класс? Это ведь не потребует усложнения синтаксиса. Просто у структуры появится деструктор с детерминированным временем вызова. C>А ты дальше подумай — что делать, если эта структура будет полем класса, уничтожение которого недетерминировано?
И что? Если ее создали на стеке — ведет себя как стековый объект. Если нет — ну нет так нет. В C++\CLI именно так и работает.
Re[3]: Сборщик мусора и размещение объектов в стеке
Здравствуйте, Константин Л., Вы писали:
C>>А ты дальше подумай — что делать, если эта структура будет полем класса, уничтожение которого недетерминировано? КЛ>И что? Если ее создали на стеке — ведет себя как стековый объект. Если нет — ну нет так нет. В C++\CLI именно так и работает.
Осталось сделать следующий шаг, и понять, что стековые объекты не нужны — достаточно паттерна Disposable и сахара в виде using().
Sapienti sat!
Re[5]: Сборщик мусора и размещение объектов в стеке
Здравствуйте, remark, Вы писали:
R>Ищи по "The Real-Time Specification for Java". Фактически они добавили синхронное освобождение памяти — схема применяемая в современном С++.
Java RTS и Java SE — как говорится найти 10 отличий. Причем тут оно?
И потом, RTS вроде какой-то древнючий JRS-... какой-то там чуть не под первым номером с коммерческой реализацией, а я говорил про Java SE 6.
Re[4]: Сборщик мусора и размещение объектов в стеке
Здравствуйте, Cyberax, Вы писали:
C>Осталось сделать следующий шаг, и понять, что стековые объекты не нужны — достаточно паттерна Disposable и сахара в виде using().
Не нужны кому, программисту просто как сахар? Ну тогда да. В принципе, и без конструкции using даже можно жить не чихая.
Здравствуйте, remark, Вы писали:
R>Техника значительно шире. Например, с помощью стекового объекта может контролироваться временный перевод курсора в "часики", блокировка/разблокировка мьютекса, задержка/возобновление обновления графического элемента управления, резервирование/разрезервирование какого-либо места/счётчика и т.д. и т.д.
Это прекрасно реализуется при помощи using. Более того, именно для таких фич using предпочтительнее, потому что явно выделяет регион действия и при чтении сразу видно, что и как происходит.
R>Так же техника применяется для обеспечения транзакционности, когда действие, выполняемое в деструкторе объекта, отменяется методом commit().
Вот как раз под рукой из DSL Tools:
using (var tran = partition.Store.TransactionManager.BeginTransaction())
{
...
tran.Commit();
}
R> Например транзакционная вставка в 3 контейнера (всё или ничего): R>
R>Если у объекта типа push_back_tx не был вызван метод commit(), то в деструкторе он удаляет из контейнера элемент, который вставил в конструкторе. R>Как это будет выглядеть в языке без стековой семантики? Я не видел красивого и *масштабируемого* решения.
Аналогично
using (var tx1 = v1.TxPushBack(1))
using (var tx2 = v2.TxPushBack(2))
{
v3.PushBack(3);
tx1.Commit();
tx2.Commit();
}
R>Хммм... Такие заявления ставят под сомнение твоё умение программировать на языках со стековой семантикой... R>Если время жизни объекта не совпадает с временем проведенным в процедуре, то объект создаётся в динамической памяти, а на стеке создаётся объект, контролирующий время жизни первого объекта:
И счетчик с количеством использований? Это, мягко говоря, не очень стыкуется с GC.
R>Такой приём является абсолютно отработанным и обыденным в современном С++. Это не составляет никакой проблемы.
Для этого, помимо стековой семантики, нужен еще и автоматический вызов деструкторов всех членов класса.
... << RSDN@Home 1.2.0 alpha rev. 725 on Windows Vista 6.0.6000.0>>
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, Константин Л., Вы писали:
C>>>А ты дальше подумай — что делать, если эта структура будет полем класса, уничтожение которого недетерминировано? КЛ>>И что? Если ее создали на стеке — ведет себя как стековый объект. Если нет — ну нет так нет. В C++\CLI именно так и работает. C>Осталось сделать следующий шаг, и понять, что стековые объекты не нужны — достаточно паттерна Disposable и сахара в виде using().
Шаг к чему? К дао? Достаточно понять, что using менее сладок нежели стековые объекты.
Здравствуйте, remark, Вы писали:
VD>>На самом деле после некоторого опыта использования управляемых языков понимашь, что страхи плюсовиков (коим я являлся до перехода на управляемые среды) сильно надуманы. 99% контроля ресурсов — это контроль памяти. А когда память не нужно пасти, то остальное можно хоть руками контролировать. В общем using-а за глаза хватает.
R>Ресурсами, которые контролируются стековым объектом, могут быть не только такие объекты как соединение, файл и т.д. R>Техника значительно шире. Например, с помощью стекового объекта может контролироваться временный перевод курсора в "часики", блокировка/разблокировка мьютекса, задержка/возобновление обновления графического элемента управления, резервирование/разрезервирование какого-либо места/счётчика и т.д. и т.д.
Тут складывается весьма странная ситуация. Ты рассказываешь мне про то что я и сам пробовал и не согласен с тем, что разве что видел из далека. Продолжай в том же духе. Это очень "конструктивная" позиция.
Здравствуйте, Константин Л., Вы писали:
КЛ>Здравствуйте, Cyberax, Вы писали:
C>>Здравствуйте, Константин Л., Вы писали:
C>>>>А ты дальше подумай — что делать, если эта структура будет полем класса, уничтожение которого недетерминировано? КЛ>>>И что? Если ее создали на стеке — ведет себя как стековый объект. Если нет — ну нет так нет. В C++\CLI именно так и работает. C>>Осталось сделать следующий шаг, и понять, что стековые объекты не нужны — достаточно паттерна Disposable и сахара в виде using().
КЛ>Шаг к чему? К дао? Достаточно понять, что using менее сладок нежели стековые объекты.