Наибольшее количество утечек памяти происходит из-за сбоев в реализации, в Java большинство основано на недостаточном понимании используемой технологии.(например, 4 различных вида внутренних классов)
Единственный способ, который помогает здесь, это тратить время и деньги на навыки разработчиков.- Лучшее чтение Effective Java Second Edition Джошуа Блоха
Другая область, которая часто вызывает утечки памяти, - это параллелизм.- Насколько мне известно, лучший способ справиться с этим (и другими проблемами параллелизма) состоит в том, чтобы определить, какие компоненты должны быть сохранены (и какие выполняются в среде с одним потоком) ПЕРЕД их реализацией.И если они должны быть реализованы с сохранением потоков, то определите ДО того, как ТОЛЬКО реализуете, ЧТО ТОЛЬКО они гарантируют, что они сохранят потоки (какие функции и методы защищены чем).
Последнее, что вы можете сделать в дизайне,обратите внимание на статические поля.
Еще одна мысль, которую вы можете сделать по своему замыслу, - это создать сторожевой таймер.Если у вас есть (например) динамический список, где нет большой проблемы, когда некоторые элементы списка теряются, и вы знаете, что список может быть причиной некоторых проблем (сбои в потоке или реализации), тогда реализуйтесторожевой таймер, который очищает список, если он становится намного больше, чем вы ожидаете.(А затем: исправьте ошибку, которая вызывает проблему!) - Примером такого списка может быть список событий обновления GUI фондовой биржи (на не относящемся к акции веб-сайте).Если одно обновление курса отправляется не клиенту, а следующему (одна секунда спустя), то потеря одного обновления намного лучше, чем сбой всего сервера.