Данный список не в коей мере не претендует на полноту или ещё на что-либо. Просто набор моментов, которые показались мне интересными.
Неожиданное исчерпание свободной памяти.
Возникает при использовании пиннинга памяти. Не обязательно явном. Например при использовании асинхронного ввода-вывода ран-тайм скорее всего сам будет делать пиннинг памяти. В CLI такая возможность так же присутствует в явном виде, в Java — не знаю. Суть пиннинга — запрещение перемещения объекта в памяти. Это может препятствовать "уплотнению" используемой памяти во время сборки мусора, таким образом используемая память будет сильно фрагментирована и "кпд" использования памяти резко снижается.
Здесь можно прочитать более подробно. Кратко суть такая: в C# при использовании асинхронных сокетов (IOCP) в сервере заканчивалось 3GB памяти (летели OutOfMemoryException), хотя "полезных" данных в памяти было примерно 200MB.
Постепенная и периодическая деградация производительности и рост используемой памяти под нагрузкой.
Подробности
здесь. Кратко: в Java при использовании WeakHashMap и включении Concurrent GC вместо штатного начали проявляться упомянутые эффекты. Оказалось, что под нагрузкой большую часть элементов WeakHashMap постоянно "трогают", хотя реально не используют. Это "троганье" предотвращало удаление каких-либо объектов из WeakHashMap вообще. Соответственно он неограниченно рос, пока весь сервер не затыкался на некоторое время. Во время затыкания элементы WeakHashMap никто не "трогал", и соотв. они все удалялись. Все становится хорошо. А потом по новой. Со штатным GC такой эффект не наблюдается.
Ну более-менее стандартная проблема с временем жизни и владением объектами.
Многие по началу считают, что при наличии GC этих проблем просто нет. К сожалению это не так. GC обеспечивает только базовую потокобезопасность для ссылок (можно захватывать новые ссылки на объект, только если у тебя уже есть хотя бы одна), но не обеспечивает строгой потокобезопасности для ссылок (возможность захватывать новые ссылки на объект, если у тебя ещё нет ни одной). Т.о. если необходима строгая потокобезопасность, то — мьютекс + счётчик ссылок... Что-то мне это напоминает...
Один из примеров можно поглядеть
здесь
Первые две проблемы от того, что GC хотят сделать полностью прозрачным и скрытым от программиста, типа он просто магически работает. К сожалению, полностью прозрачен он только на абстрактном уровне. Когда дело доходит до самых деталей начинается самое интересное — побочные эффекты GC становятся видны. Отсюда ещё одно неприятное следствие — программа хорошо работающая с одним типом или даже скорее реализацией GC, совсем не обязательно будет хорошо работать с другой.
Третья проблема от огромных лозунгов, что все проблемы с управлением памятью и иже с ними временем жизни и владением — решены GC. GC решена только проблема управлением памятью. А время жизни и владение, как были одними из сложных проблем разработки ПО, так ими и остались. И эти моменты по прежнему надо продумывать и контролировать вручную.
Какие мысли?
12.09.07 03:28: Перенесено из 'Архитектура программного обеспечения'