Здравствуйте, Pavel Dvorkin, Вы писали: PD>Из неуправляемой кучи ссылок на управляемые объекты и обратно быть не должно. Не держишь же ты в С++ куче ссылки на автоматические объекты в стеке PD>Я просто предлагаю разделить эти два множества без пересечения.
Такое уже есть. И давно. Только получается, что это не одна коробка, а две коробки.
PD>Почему ? Совместили же в C# кучу и стек. Я не вижу, почему стек с GC может в одной коробке уживаться, а неуправляемая куча нет.
Ну так посмотри повнимательнее. С GC кстати уживается вовсе не любой стек, а только очень специальный. Обрати внимание, что в дотнете в стеке не могут жить объекты ссылочного типа. PD>В конце концов стек от неуправляемой кучи отличается только механизмом выделения/освобожденяи памяти, если уж на то пошло
Cтек еще много чем отличается. В частности, для того, чтобы стек был безопасным, необходимо запрещать возврат указателей на элементы стека. В управляемых языках так и сделано, а в неуправляемых всё плохо. В куче гарантировать отсутствие циклов невозможно.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>У меня на все это одна мысль возникла. А почему бы авторам некоей системы программирования не совместить GC и не-GC в одной коробке ? То есть ввести в систему GC и его управление памятью, но в то же оставить и возможность выделять/освобождать память вручную. 2 кучи — одна управляемая a la C#-Java, вторая — неуправляемая a la C++. И были бы и волки сыты и овцы целы. Выбирай, что тебе больше нравится и что больше соотвествует твоей задаче. А может быть, даже и в рамках одной задачи выбирать и то и другое для разных объектов.
Такие попытки были. В Modula-3 два типа указателей traced и untraced и, соответственно две кучи.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Кстати, то же относится к деструктированию объектов. Почему бы не сделать так, чтобы программист мог либо поручить это GC, либо сказать — делай детерминированно сейчас ?
Снова изобретаем велосипед?
В управляемых платформах уже есть инструмент детерминирования финализации объектов: кроме жестких ссылок, есть гибкие (WeakReference<T>), легкие (SoftReference<T>) и фантомные (PhantomReference<T>) ссылки — что в Java, что в .NET.
PD>Никаких принципиальных причин, почему это невозможно, я не вижу (если кто видит — скажите). Конечно, в нынешние языки и системы это не лезет. Может, пора новый язык/систему создать с такими возможностями.
И что ж это интересно рукам покоя не дает?
Здравствуйте, Pavel Dvorkin, Вы писали: PD>Вдогонку. А кстати, почему в C# жестко привязали тип объектов (object или value) к способу размещения (куча или стек). Почему нельзя value разместить в куче или object в стеке ? Это принципиально или просто особенность реализации ?
Во-первых, value в куче разместить можно. RTFM "Boxing".
Во-вторых, ссылочный тип в стеке разместить нельзя по принципиальным соображениям: ссылка на такой объект может пережить разрушение фрейма стека и окажется повисшей. А GC собственно придуман для гарантии ссылочной целостности.
Обратное также верно: если ни одна ссылка на объект не может пережить разрушения соответствующего фрейма стека, то объект таки можно разместить в стеке. В новой джаве это реализовано; RTFM "Escape Analysis".
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>У меня на все это одна мысль возникла. А почему бы авторам некоей системы программирования не совместить GC и не-GC в одной коробке ? То есть ввести в систему GC и его управление памятью, но в то же оставить и возможность выделять/освобождать память вручную. 2 кучи — одна управляемая a la C#-Java, вторая — неуправляемая a la C++. И были бы и волки сыты и овцы целы. Выбирай, что тебе больше нравится и что больше соотвествует твоей задаче. А может быть, даже и в рамках одной задачи выбирать и то и другое для разных объектов.
В D http://www.digitalmars.com/d/index.html именно так.
PD>Кстати, то же относится к деструктированию объектов. Почему бы не сделать так, чтобы программист мог либо поручить это GC, либо сказать — делай детерминированно сейчас ?
В D есть и RAII и GC и полное ручное управление (переопределяймы new)
PD>Никаких принципиальных причин, почему это невозможно, я не вижу (если кто видит — скажите). Конечно, в нынешние языки и системы это не лезет. Может, пора новый язык/систему создать с такими возможностями.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Pavel Dvorkin, Вы писали: S>Во-первых, value в куче разместить можно. RTFM "Boxing".
Спасибо, а то я не слышал до сих пор об этом. Только это уже не совсем value ИМХО
S>Во-вторых, ссылочный тип в стеке разместить нельзя по принципиальным соображениям: ссылка на такой объект может пережить разрушение фрейма стека и окажется повисшей. А GC собственно придуман для гарантии ссылочной целостности.
Неубедительно. Я не говорю о C# и .Net, но можно представить себе среду, в которой для ссылок на объекты в стеке при разрушении фрейма стека автоматически вызывается "деструктор". Ее кстати и придумывать не надо — C++ unmanaged.
S>Обратное также верно: если ни одна ссылка на объект не может пережить разрушения соответствующего фрейма стека, то объект таки можно разместить в стеке. В новой джаве это реализовано; RTFM "Escape Analysis".
Вот с этим я не знаком. Судя по всему, это аналог того же самого, что и в C++.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Pavel Dvorkin, Вы писали: PD>>Почему ? Совместили же в C# кучу и стек. Я не вижу, почему стек с GC может в одной коробке уживаться, а неуправляемая куча нет. S>Ну так посмотри повнимательнее. С GC кстати уживается вовсе не любой стек, а только очень специальный. Обрати внимание, что в дотнете в стеке не могут жить объекты ссылочного типа.
А нельзя ли объяснить, что такое специальный стек — кроме того, что ты сказал выше, в нем что-то еще особеннное есть ?
PD>>В конце концов стек от неуправляемой кучи отличается только механизмом выделения/освобожденяи памяти, если уж на то пошло S>Cтек еще много чем отличается. В частности, для того, чтобы стек был безопасным, необходимо запрещать возврат указателей на элементы стека.
Равно как и в куче решительно не рекомендуется возвращать указатели на удаленные уже объекты
>В управляемых языках так и сделано, а в неуправляемых всё плохо.
А что тут плохого ?
int* f ()
{
int x;
return &x;
}
warning C4172: returning address of local variable or temporary
Ладно, участие в этой дискуссии прекращаю. Твои аргументы серьезны, но не окончательны. Тем более, что ряд участников этого фрагмента дискуссии привели примеры, где это уже есть. Так что будущее нас рассудит
Здравствуйте, rsn81, Вы писали:
R>В управляемых платформах уже есть инструмент детерминирования финализации объектов: кроме жестких ссылок, есть гибкие (WeakReference<T>), легкие (SoftReference<T>) и фантомные (PhantomReference<T>) ссылки — что в Java, что в .NET.
Всё перечисленное, это как раз недетерменированно.
Здравствуйте, FR, Вы писали:
PD>>Кстати, то же относится к деструктированию объектов. Почему бы не сделать так, чтобы программист мог либо поручить это GC, либо сказать — делай детерминированно сейчас ?
FR>В D есть и RAII и GC и полное ручное управление (переопределяймы new)
PD>>Никаких принципиальных причин, почему это невозможно, я не вижу (если кто видит — скажите). Конечно, в нынешние языки и системы это не лезет. Может, пора новый язык/систему создать с такими возможностями.
FR>Уже есть, при том язык вполне близкий к C++.
Имхо, сейчас это "есть" определяется всего лишь наличием dsource.org и высоким рейтингом D в индексе TIOBE. А с учетом того, что разработчики не стабилизировав и не доведя до ума D1.0 затеяли долгий путь в неизвестность под названием D2.0 -- его присутствие становится, имхо, виртуальным.
Касательно данной темы, в D попыткой внедрить в C/C++ семейство сборщик мусора насыпали довольно много мелких камешков для программистов. Наличие примитивных типов (value types), структур (опять value types), классов (reference types) и на все это ссылок и указателей затрудняет восприятие языка (и программирование на шаблонах). А попытка навесить на все это константность делает ситуацию еще хуже.
Так что эксперимент по сочетанию в D ручного управления памятью и сборщика мусора еще только развивается и о результатах следить рановато.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, remark, Вы писали:
R>Приемущество "Сишных" malloc/free в данном контексте — они просты как 2 копейки. В них просто нет ничего, что могло бы вообще вызывать какие-либо нарекания, или какие-либо проблемы. Именно они сами, не то, как их использовать. R>Я не помню, что бы слышал какие либо нарекания именно в адрес самих malloc/free. Да, это низкоуровневое средство. И оно хорошо делает одну чётко определённую вещь...
Ну, услышь: в условиях многопоточности, если куча не lock-free, можно на ровном месте поймать инверсию приоритетов — и, соответственно, внезапную просадку производительности.
В реалтайме это очень раздражает.
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, remark, Вы писали:
R>>Здесь можно прочитать более подробно. Кратко суть такая: в C# при использовании асинхронных сокетов (IOCP) в сервере заканчивалось 3GB памяти (летели OutOfMemoryException), хотя "полезных" данных в памяти было примерно 200MB. C>В Java для асинхронного и memory-mapped IO используются unmanaged-буфферы, которые располагаются отдельно от основной кучи. Пиннинг делается только для критичных по скорости кусков нативного кода.
Т.е. получается, что если у меня данные уже лежат в каком-то буфере, то, что бы отправить их в сеть, я обязан их всё равно скопировать в этот специальный буфер (не или фреймворк это сделает, неважно)? Но это же убивает идею на корню...
R>>Многие по началу считают, что при наличии GC этих проблем просто нет. К сожалению это не так. GC обеспечивает только базовую потокобезопасность для ссылок (можно захватывать новые ссылки на объект, только если у тебя уже есть хотя бы одна), но не обеспечивает строгой потокобезопасности для ссылок (возможность захватывать новые ссылки на объект, если у тебя ещё нет ни одной). Т.о. если необходима строгая потокобезопасность, то — мьютекс + счётчик ссылок... Что-то мне это напоминает... R>>Один из примеров можно поглядеть здесь C>В данном случае мьютекс+счетчик — плохое решение. Дело в том, что работать с формой можно безопасно только из одного потока. Нужно было замаршалить вызов в GUI-поток, тогда никаких гонок бы не было.
Дело не в форме и таймере, это может быть с любыми объектами
R>>Какие мысли? C>Примеры надо покрасивее придумать
А я не придумывал
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, remark, Вы писали:
R>>Это абсолютно не бага. Это архитектурная несовместимость GC и асинхронного высокопроизводительного zero-copy ввода-вывода. WH>Это исключительно из-за того что ОС не правильной системы. WH>Если бы ОС была правильной то никакой несовместимости бы небыло... оно бы еще и быстрее чем на классических ОС работало...
Ты ещё скажи, что они неправильное соглашение об именовании идентификаторов использовали, поэтому всё плохо. А вот если бы правильно идентификаторы называли...
Здравствуйте, Кодт, Вы писали:
R>>Приемущество "Сишных" malloc/free в данном контексте — они просты как 2 копейки. В них просто нет ничего, что могло бы вообще вызывать какие-либо нарекания, или какие-либо проблемы. Именно они сами, не то, как их использовать. R>>Я не помню, что бы слышал какие либо нарекания именно в адрес самих malloc/free. Да, это низкоуровневое средство. И оно хорошо делает одну чётко определённую вещь...
К>Ну, услышь: в условиях многопоточности, если куча не lock-free, можно на ровном месте поймать инверсию приоритетов — и, соответственно, внезапную просадку производительности. К>В реалтайме это очень раздражает.
Поэтому в реалтайме стараются динамической памятью не пользоваться. И чем жесче рилтайм, тем больше стараются. Вплоть до полного отрицания динамической памяти как явления
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, WolfHound, Вы писали:
R>>Это абсолютно не бага. Это архитектурная несовместимость GC и асинхронного высокопроизводительного zero-copy ввода-вывода. WH>Это исключительно из-за того что ОС не правильной системы. WH>Если бы ОС была правильной то никакой несовместимости бы небыло... оно бы еще и быстрее чем на классических ОС работало...
Благородный дон предлагает нам всем пересесть на AS/400?
Здравствуйте, remark, Вы писали:
C>>В Java для асинхронного и memory-mapped IO используются unmanaged-буфферы, которые располагаются отдельно от основной кучи. Пиннинг делается только для критичных по скорости кусков нативного кода. R>Т.е. получается, что если у меня данные уже лежат в каком-то буфере, то, что бы отправить их в сеть, я обязан их всё равно скопировать в этот специальный буфер (не или фреймворк это сделает, неважно)? Но это же убивает идею на корню...
Если данные уже лежат в NIO-буффере, то просто отдаешь его асинхронному IO. Если же они у тебя в обычном массиве — придется формировать буффер.
R>>>Один из примеров можно поглядеть здесь C>>В данном случае мьютекс+счетчик — плохое решение. Дело в том, что работать с формой можно безопасно только из одного потока. Нужно было замаршалить вызов в GUI-поток, тогда никаких гонок бы не было. R>Дело не в форме и таймере, это может быть с любыми объектами
Так тут простейшие гонки. Просто тупо предусмотреть два логических состояния объекта и тупо игнорировать сообщения таймера в неправильном.
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, remark, Вы писали:
C>>>В Java для асинхронного и memory-mapped IO используются unmanaged-буфферы, которые располагаются отдельно от основной кучи. Пиннинг делается только для критичных по скорости кусков нативного кода. R>>Т.е. получается, что если у меня данные уже лежат в каком-то буфере, то, что бы отправить их в сеть, я обязан их всё равно скопировать в этот специальный буфер (не или фреймворк это сделает, неважно)? Но это же убивает идею на корню... C>Если данные уже лежат в NIO-буффере, то просто отдаешь его асинхронному IO. Если же они у тебя в обычном массиве — придется формировать буффер.
Шило на мыло...
R>>>>Один из примеров можно поглядеть здесь C>>>В данном случае мьютекс+счетчик — плохое решение. Дело в том, что работать с формой можно безопасно только из одного потока. Нужно было замаршалить вызов в GUI-поток, тогда никаких гонок бы не было. R>>Дело не в форме и таймере, это может быть с любыми объектами C>Так тут простейшие гонки. Просто тупо предусмотреть два логических состояния объекта и тупо игнорировать сообщения таймера в неправильном.
Да, простейшие гонки. Но многие изначально наивно считают, что GC решает такие проблемы.
Два состояния — хорошо. А если второе состояние — это объект удалён? Надо делать либо отдельный прокси, либо выносить этот флаг куда-то ещё...
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Всё перечисленное, это как раз недетерменированно.
Детерминировано на том уровне, на котором это в принципе возможно в среде с GC.
Здравствуйте, Pavel Dvorkin, Вы писали: PD>Спасибо, а то я не слышал до сих пор об этом. Только это уже не совсем value ИМХО
Вполне себе совсем. Вместе с оснасткой, необходимой для успешного существования в куче. S>>Во-вторых, ссылочный тип в стеке разместить нельзя по принципиальным соображениям: ссылка на такой объект может пережить разрушение фрейма стека и окажется повисшей. А GC собственно придуман для гарантии ссылочной целостности. PD>Неубедительно. Я не говорю о C# и .Net, но можно представить себе среду, в которой для ссылок на объекты в стеке при разрушении фрейма стека автоматически вызывается "деструктор". Ее кстати и придумывать не надо — C++ unmanaged.
Ничего подобного в C++ unmanaged нету. Вернуть ссылку на стековый объект в нем — как четыре байта переслать. PD>Вот с этим я не знаком. Судя по всему, это аналог того же самого, что и в C++.
Нет. Ничего подобного в С++ нету. Никаким анализом компилятор не занимается, если написал new — будет тебе new. Разница между автоматическим анализатором, принимающим решение, можно ли разместить конкретный экземпляр в стеке, и компилятором, который умнее инлайнинга ничего не делает, понятна невооруженным мозгом.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Pavel Dvorkin, Вы писали: PD>А нельзя ли объяснить, что такое специальный стек — кроме того, что ты сказал выше, в нем что-то еще особеннное есть ?
Да, в частности нельзя взять ссылку на стековый объект. Точнее, нельзя вернуть ссылку на стековый объект вверх; вниз — можно. PD>>>В конце концов стек от неуправляемой кучи отличается только механизмом выделения/освобожденяи памяти, если уж на то пошло S>>Cтек еще много чем отличается. В частности, для того, чтобы стек был безопасным, необходимо запрещать возврат указателей на элементы стека. PD>Равно как и в куче решительно не рекомендуется возвращать указатели на удаленные уже объекты
В GC-куче понятие "указатели на удаленный объект" является оксюмороном.
PD>А что тут плохого ?
PD>
PD>int* f ()
PD>{
PD> int x;
PD> return &x;
PD>}
PD>
PD>warning C4172: returning address of local variable or temporary PD>VS 2005, SP1
Это легко обмануть:
int* f ()
{
int x;
return crashHelper(&x);
}
int* crashHelper(int* pX)
{
return pX;
}
Силы темная сторона давно над C++ возобладала.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.