Здравствуйте, Sinclair, Вы писали:
S>В GC-куче понятие "указатели на удаленный объект" является оксюмороном.
Вот именно про это я и говорил в первом посте
Многие считают, что среда с GC предоставляет многопоточную безопасность в сильном смысле (захват объекта, если ещё нет ссылки на него). GC этого *не* предоставляет. Он предоставляет только *базовую* многопоточную безопасность.
Читаем ещё раз здесь
И думаем над исключением 'Disposed object cannot be accessed'
Здравствуйте, rsn81, Вы писали:
ANS>>Всё перечисленное, это как раз недетерменированно. R>Детерминировано на том уровне, на котором это в принципе возможно в среде с GC.
Хе-хе. Звучит как речь политика Но суть то, не меняется.
Здравствуйте, remark, Вы писали: R>Многие считают, что среда с GC предоставляет многопоточную безопасность в сильном смысле (захват объекта, если ещё нет ссылки на него). GC этого *не* предоставляет. Он предоставляет только *базовую* многопоточную безопасность.
R>Читаем ещё раз здесь R>И думаем над исключением 'Disposed object cannot be accessed'
Думать тут нечего. Никакого отношения к GC это не имеет. Поясняю еще раз на пальцах: GC обеспечивает только управление памятью. Он не обеспечивает никакого управления состоянием объекта.
В частности, с этим связаны интересные эффекты в самодельных синглтонах, когда "более шустрый второй поток" успевает выхватить свежесозданный синглтон из рук первого потока, и начать терзать его не дожидаясь инициализации.
В частности, с этим связаны спецэффекты с формами, которые уже отдиспозены к моменту обращения к ним из другого потока.
Это совершенно неважно. Если ты удерживаешь ссылку на IDisposable объект, надо быть всегда готовым к тому, что он может неожиданно задиспозиться. Даже в однопотоковом приложении.
Тем не менее, объект всё еще будет "жив" в том смысле, что его память будет принадлежать именно ему.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, remark, Вы писали: R>>Многие считают, что среда с GC предоставляет многопоточную безопасность в сильном смысле (захват объекта, если ещё нет ссылки на него). GC этого *не* предоставляет. Он предоставляет только *базовую* многопоточную безопасность.
R>>Читаем ещё раз здесь R>>И думаем над исключением 'Disposed object cannot be accessed' S>Думать тут нечего. Никакого отношения к GC это не имеет. Поясняю еще раз на пальцах: GC обеспечивает только управление памятью. Он не обеспечивает никакого управления состоянием объекта. S>В частности, с этим связаны интересные эффекты в самодельных синглтонах, когда "более шустрый второй поток" успевает выхватить свежесозданный синглтон из рук первого потока, и начать терзать его не дожидаясь инициализации. S>В частности, с этим связаны спецэффекты с формами, которые уже отдиспозены к моменту обращения к ним из другого потока. S>Это совершенно неважно. Если ты удерживаешь ссылку на IDisposable объект, надо быть всегда готовым к тому, что он может неожиданно задиспозиться. Даже в однопотоковом приложении. S>Тем не менее, объект всё еще будет "жив" в том смысле, что его память будет принадлежать именно ему.
Чем не "указатель на удаленный объект"? За исключением терминологии и деталей?
Происходит нарушение защиты памяти, расстрел памяти или исключение не суть важно.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Хе-хе. Звучит как речь политика Но суть то, не меняется.
А пока и не было веских аргументов, что необходима позарез большая степень детерминирования в сфере программирования на управляемых средах.
Здравствуйте, remark, Вы писали:
R>Чем не "указатель на удаленный объект"? За исключением терминологии и деталей?
Всем. Вместо слова "удаленный" можно также использовать "приближенный", "окрашенный", "изогнутый" и прочие прилагательные, характеризующие состояние.
Если ваше подсознание протестует против того, чтобы объект, ссылку на который удерживает ваш код, оказался disposed, выбросьте ваше подсознание.
Вот простейший пример неожиданного поведения:
public class Formatter
{
public string Format
{
set { _format = value; }
}
}
private string _format;
public string DoFormat(object a, object b)
{
return string.Format(_format, a, b);
}
public static Formatter F = new Formatter();
}
Вот код потока 1:
public string AundB(int a, int b)
{
Formatter.F.Format = "{0} + {1}";
return Formatter.F.DoFormat(a, b);
}
Если в это время поток 2 выполнит Formatter.F.Format = null, получим NPE. За исключением терминологии и деталей это то же самое, что и описываемое в статье поведение. Кто ожидал, что от этого NPE защитит GC, поднимите руки! А?
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, remark, Вы писали:
R>Чем не "указатель на удаленный объект"? За исключением терминологии и деталей? R>Происходит нарушение защиты памяти, расстрел памяти или исключение не суть важно.
Дьявол в мелочах. В одном случае получаем аборт приложения в другом ловим исключение, обрабатываем его, логируем и при завершении, по крайней мере, пытаемся вернуть окружающую среду "как было".
Здравствуйте, anton_t, Вы писали:
_>Здравствуйте, remark, Вы писали:
R>>Чем не "указатель на удаленный объект"? За исключением терминологии и деталей? R>>Происходит нарушение защиты памяти, расстрел памяти или исключение не суть важно.
_>Дьявол в мелочах. В одном случае получаем аборт приложения в другом ловим исключение, обрабатываем его, логируем и при завершении, по крайней мере, пытаемся вернуть окружающую среду "как было".
Это тут, по-моему, вообще не существенно. Под Win32 это делается аналогично и при нарушении защиты памяти.
Здравствуйте, remark, Вы писали:
R>Данный список не в коей мере не претендует на полноту или ещё на что-либо. Просто набор моментов, которые показались мне интересными.
Я вообще никакой философии не предполагал...
Просто описал ряд конкретных моментов имеющих место быть. Вообще хотел написать (да забыл) — может кто ещё интересных примеров может привести? Мне кажется, должны быть. Я не сказать что бы годами собирал этот список.
R>
E>>Так что, если вспомнить закон потребления пива 20/80, то GC является отличным инструментом в 80% случаев. Зато в оставшихся 20% с ним придется бороться.
E>>Явное же управление памятью наоборот, вызывает лишние затраты в 80% случаев, зато в 20% это именно то, что нужно.
R>Да. Если ты пишешь только 80%. Если же ты пишешь и оставшиеся 20%, и соотв. у тебя есть решения для этих 20%, то не вижу смысла не применять их в других 80%. Точнее так — я не вижу больше проблемы.
Проблемы, возможно, нет научной. А производственная проблема есть — "лишние затраты", овчинка выделки не стоит. GC ее решает.
Здравствуйте, Klapaucius, Вы писали:
FR>>В D есть и RAII и GC и полное ручное управление (переопределяймы new)
K>За это приходится расплачиваться. GC в D консервативный, а не точный.
AFAIK, это деталь текущей реализации, а не принципиальная особенность языка. Разработчики Tango используют собственную версию GC, которая несколько быстрее штатной. И сама архитектура Tango подразумевает возможность смены GC. Тут вопрос упирается в то, что в D community пока никто лучшего GC не написал.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, mselez, Вы писали:
M>Здравствуйте, remark, Вы писали:
E>>>Так что, если вспомнить закон потребления пива 20/80, то GC является отличным инструментом в 80% случаев. Зато в оставшихся 20% с ним придется бороться.
E>>>Явное же управление памятью наоборот, вызывает лишние затраты в 80% случаев, зато в 20% это именно то, что нужно.
R>>Да. Если ты пишешь только 80%. Если же ты пишешь и оставшиеся 20%, и соотв. у тебя есть решения для этих 20%, то не вижу смысла не применять их в других 80%. Точнее так — я не вижу больше проблемы.
M>Проблемы, возможно, нет научной. А производственная проблема есть — "лишние затраты", овчинка выделки не стоит. GC ее решает.
Какие тут лишние затраты? Тут нет никаких лишних затрат.
Здравствуйте, eao197, Вы писали:
FR>>>В D есть и RAII и GC и полное ручное управление (переопределяймы new) K>>За это приходится расплачиваться. GC в D консервативный, а не точный. E>AFAIK, это деталь текущей реализации, а не принципиальная особенность языка. Разработчики Tango используют собственную версию GC, которая несколько быстрее штатной. И сама архитектура Tango подразумевает возможность смены GC. Тут вопрос упирается в то, что в D community пока никто лучшего GC не написал.
А на сколько я знаю, возможность использования точного GC предъявляет требования к дизайну языка. Увы — жизнь это не только музыка и цветы.
... << RSDN@Home 1.2.0 alpha rev. 730>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, remark, Вы писали:
PD><все skipped после чтения данного сообщения и ответов>
PD>У меня на все это одна мысль возникла. А почему бы авторам некоей системы программирования не совместить GC и не-GC в одной коробке ? То есть ввести в систему GC и его управление памятью, но в то же оставить и возможность выделять/освобождать память вручную. 2 кучи — одна управляемая a la C#-Java, вторая — неуправляемая a la C++. И были бы и волки сыты и овцы целы. Выбирай, что тебе больше нравится и что больше соотвествует твоей задаче. А может быть, даже и в рамках одной задачи выбирать и то и другое для разных PD> объектов.
..
Другая важная часть RTSJ—это введение новых областей памяти, отличных от обычной кучи (heap), используемой в Java. Работа с этими областями памяти осуществляется с помощью класса ScopedMemory. Объекты ScopedMemory должны создаваться непосредственно программистом, например:
// создать область памяти размером 1MB (LTMemory — стандартный подкласс ScopedMemory)
ScopedMemory scopedMemory = new LTMemory(1024 * 1024);
Создаваемая таким образом память не управляется сборщиком мусора. Очищаются эти области памяти в тот момент, когда не остаётся работающих в них потоков. Рамки использования памяти задаются синтаксически: поток использует ScopedMemory, пока он выполняет метод ScopedMemory.enter. Также надо отметить, что области ScopedMemory доступны только для потоков реального времени.
..
Здравствуйте, Klapaucius, Вы писали:
FR>>>>В D есть и RAII и GC и полное ручное управление (переопределяймы new) K>>>За это приходится расплачиваться. GC в D консервативный, а не точный. E>>AFAIK, это деталь текущей реализации, а не принципиальная особенность языка. Разработчики Tango используют собственную версию GC, которая несколько быстрее штатной. И сама архитектура Tango подразумевает возможность смены GC. Тут вопрос упирается в то, что в D community пока никто лучшего GC не написал.
K>А на сколько я знаю, возможность использования точного GC предъявляет требования к дизайну языка.
Ирония в том, что для D консервативный GC опаснее, чем точный. Поскольку консервативный GC не в состоянии отличить значения float, полученные в результате каких-нибудь расчетов, от указателей. И вполне может принять массив float-ов за массив указателей. Что и просходило вскоре после выпуска D1.0 и что обсуждалось в digitalmars.D. Поэтому уже в D1.001 GC был изменен так, чтобы использовать информацию о типах.
K>Увы — жизнь это не только музыка и цветы.
Да, я здесь громче всех утверждаю, что в жизни есть только музыка и цветы. Спасибо, что напомнили.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, remark, Вы писали:
R>Неожиданное исчерпание свободной памяти. R>Возникает при использовании пиннинга памяти. Не обязательно явном. Например при использовании асинхронного ввода-вывода ран-тайм скорее всего сам будет делать пиннинг памяти. В CLI такая возможность так же присутствует в явном виде, в Java — не знаю. Суть пиннинга — запрещение перемещения объекта в памяти. Это может препятствовать "уплотнению" используемой памяти во время сборки мусора, таким образом используемая память будет сильно фрагментирована и "кпд" использования памяти резко снижается. R>Здесь можно прочитать более подробно. Кратко суть такая: в C# при использовании асинхронных сокетов (IOCP) в сервере заканчивалось 3GB памяти (летели OutOfMemoryException), хотя "полезных" данных в памяти было примерно 200MB.
Проблема была вызвана кривым решением в CLR. На сегодня она исправлена (если не ошибаюсь во Фрэймворке 2.0 ее уже нет).
Ввывод — это не проблема GC в общем, а проблема конкретной реализации.
R>Постепенная и периодическая деградация производительности и рост используемой памяти под нагрузкой. R>Подробности здесь. Кратко: в Java при использовании WeakHashMap и включении Concurrent GC вместо штатного начали проявляться упомянутые эффекты. Оказалось, что под нагрузкой большую часть элементов WeakHashMap постоянно "трогают", хотя реально не используют. Это "троганье" предотвращало удаление каких-либо объектов из WeakHashMap вообще. Соответственно он неограниченно рос, пока весь сервер не затыкался на некоторое время. Во время затыкания элементы WeakHashMap никто не "трогал", и соотв. они все удалялись. Все становится хорошо. А потом по новой. Со штатным GC такой эффект не наблюдается.
Опять же... Сам говришь, что проблема проявляется только с кокретной реализацией GC. Значит и это проблема реализации.
R>Ну более-менее стандартная проблема с временем жизни и владением объектами. R>Многие по началу считают, что при наличии GC этих проблем просто нет. К сожалению это не так. GC обеспечивает только базовую потокобезопасность для ссылок (можно захватывать новые ссылки на объект, только если у тебя уже есть хотя бы одна), но не обеспечивает строгой потокобезопасности для ссылок (возможность захватывать новые ссылки на объект, если у тебя ещё нет ни одной). Т.о. если необходима строгая потокобезопасность, то — мьютекс + счётчик ссылок... Что-то мне это напоминает... R>Один из примеров можно поглядеть здесь
Ни Ява, ни дотнет не содержат серьзных средств упрощающих многопоточную разработку. GC тут просто не причем. Более того есть системы с GC которые как раз радикально упрощают разработку многопточных систем (Эрлэнг, Сингулярити и т.п.).
R>Какие мысли?
Мысль одна. Не следует обсуждать слухи. А уж если полез обсуждать, то разберись в проблематике.
GC не иделное решене. У него есть проблемы. Одна из главных проблем — это увеличение потребности в памяти. GC работает эффективно только при наличии запаса свободной памяти. Он как бы меняет лишнюю память на автоматическое упрваление ею.
Кроме того GC сам по себе не предоставляет средств управления другими ресурсами и выявления проблем с неосвобождением памяти (складыванием ее в кучу). Однако эти проблемы могут быть решены отладчиками, языками программирования и инструментальными средствами.
Ну, а описанные здесь "проблемы" не более чем громкие охания.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, remark, Вы писали:
R>>Неожиданное исчерпание свободной памяти. R>>Возникает при использовании пиннинга памяти. Не обязательно явном. Например при использовании асинхронного ввода-вывода ран-тайм скорее всего сам будет делать пиннинг памяти. В CLI такая возможность так же присутствует в явном виде, в Java — не знаю. Суть пиннинга — запрещение перемещения объекта в памяти. Это может препятствовать "уплотнению" используемой памяти во время сборки мусора, таким образом используемая память будет сильно фрагментирована и "кпд" использования памяти резко снижается. R>>Здесь можно прочитать более подробно. Кратко суть такая: в C# при использовании асинхронных сокетов (IOCP) в сервере заканчивалось 3GB памяти (летели OutOfMemoryException), хотя "полезных" данных в памяти было примерно 200MB.
VD>Проблема была вызвана кривым решением в CLR. На сегодня она исправлена (если не ошибаюсь во Фрэймворке 2.0 ее уже нет).
А как они решили? Как в Java?
VD>Ввывод — это не проблема GC в общем, а проблема конкретной реализации.
Это всё проблемы реализаций. Точнее так — это проблемы, с которыми можно сталкнуться в реальности, если используешь GC. Возможно я немного неточно назвал тему...
R>>Постепенная и периодическая деградация производительности и рост используемой памяти под нагрузкой. R>>Подробности здесь. Кратко: в Java при использовании WeakHashMap и включении Concurrent GC вместо штатного начали проявляться упомянутые эффекты. Оказалось, что под нагрузкой большую часть элементов WeakHashMap постоянно "трогают", хотя реально не используют. Это "троганье" предотвращало удаление каких-либо объектов из WeakHashMap вообще. Соответственно он неограниченно рос, пока весь сервер не затыкался на некоторое время. Во время затыкания элементы WeakHashMap никто не "трогал", и соотв. они все удалялись. Все становится хорошо. А потом по новой. Со штатным GC такой эффект не наблюдается.
VD>Опять же... Сам говришь, что проблема проявляется только с кокретной реализацией GC. Значит и это проблема реализации.
Да.
R>>Ну более-менее стандартная проблема с временем жизни и владением объектами. R>>Многие по началу считают, что при наличии GC этих проблем просто нет. К сожалению это не так. GC обеспечивает только базовую потокобезопасность для ссылок (можно захватывать новые ссылки на объект, только если у тебя уже есть хотя бы одна), но не обеспечивает строгой потокобезопасности для ссылок (возможность захватывать новые ссылки на объект, если у тебя ещё нет ни одной). Т.о. если необходима строгая потокобезопасность, то — мьютекс + счётчик ссылок... Что-то мне это напоминает... R>>Один из примеров можно поглядеть здесь
VD>Ни Ява, ни дотнет не содержат серьзных средств упрощающих многопоточную разработку. GC тут просто не причем.
GC тут косвенно при чём. Т.к. такие посты и заметки в блоках встречаются с некоторой регулярностью.
VD>Более того есть системы с GC которые как раз радикально упрощают разработку многопточных систем (Эрлэнг, Сингулярити и т.п.).
Они могли бы так же быть построены и на основе синхронного удаления объектов, используя подсчёт ссылок.
R>>Какие мысли?
VD>Мысль одна. Не следует обсуждать слухи. А уж если полез обсуждать, то разберись в проблематике.
Это не слухи. Это — факты. Факты про конкрутные реализации — не спорю.
VD>GC не иделное решене. У него есть проблемы. Одна из главных проблем — это увеличение потребности в памяти. GC работает эффективно только при наличии запаса свободной памяти. Он как бы меняет лишнюю память на автоматическое упрваление ею.
VD>Кроме того GC сам по себе не предоставляет средств управления другими ресурсами и выявления проблем с неосвобождением памяти (складыванием ее в кучу). Однако эти проблемы могут быть решены отладчиками, языками программирования и инструментальными средствами.
VD>Ну, а описанные здесь "проблемы" не более чем громкие охания.
Да, это — действительно громкие охания... человека который провёл месяц в отладчике
Здравствуйте, VladD2, Вы писали:
VD>GC не иделное решене. У него есть проблемы. Одна из главных проблем — это увеличение потребности в памяти. GC работает эффективно только при наличии запаса свободной памяти. Он как бы меняет лишнюю память на автоматическое упрваление ею.
Ты знаешь, Влад, ты мой лучший враг в спорах, но здесь я с тобой соглашусь. Ты прав. Ты растешь! Это ценно. Было особенно интересно узнать про хэш-таблицу, в которой все хеш-значения были одинаковыми. Это же был фактически exhaustive search! Вообще удивительно как все продолжало хоть как-то работать. Вот в этом-то и заключается главный недостаток GC — он жрёт мозг.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.