Два ключевой «эффективная утечка» модель в моем опыте, является:
- статики и одиночками, которые постепенно растут с течением времени. Это может включать в себя кеши, плохо реализованные и используемые пулы соединений, словари «каждого пользователя, которого мы видели с момента запуска» и т. Д.
- Ссылки на долгоживущие объекты на объекты, которые были , предназначались для недолговечного. В C# это может случиться с событиями, и эквивалентный шаблон наблюдателя может дать такой же эффект в Java. В принципе, если вы попросите один объект (наблюдателя) смотреть другой (источник), то обычно вы получаете ссылку от источник до наблюдателя. Это может стать единственной «живой» ссылкой, но она будет жить до тех пор, пока источник.
- Устраняет утечку, если вы продолжаете генерировать новый код динамически. Я нахожусь здесь на скалистом грунте, но я уверен, что столкнулся с такими проблемами. Возможно, это было отчасти из-за ошибок JRE, которые с тех пор были исправлены - это было слишком долго, так как это случилось для меня, чтобы помнить наверняка.
- Единичные тесты, которые удерживаются в состоянии, могут длиться дольше, чем вы могли ожидать, потому что JUnit будет удерживать экземпляры тестового набора. Опять же, я не могу вспомнить детали, но иногда это делает необходимость иметь явное «обнуление переменной» в отрыве, анахроничное, как это выглядит.
Я не могу сказать, что я регулярно обнаруживал утечки памяти, чтобы быть проблемой в Java (или .NET).
О, я вижу, что это происходит довольно часто, если вы используете закрытие бедняка. Вы не понимаете, что держитесь за внешний объект и все его ссылки. Это быстро становится грязным. – krosenvold