Вопрос: Как может произойти утечка памяти в Java?
О: В Java существует множество причин утечек памяти. Типичным примером является код, который не реализует hasCode и
Класс Key метода Equals сохраняется в HashMap. В конечном итоге будет создано множество повторяющихся объектов. Все утечки памяти
В конце концов будет выдано исключение OutOfMemoryError. Вот краткое моделирование утечки памяти в бесконечном цикле.
Объясните на примере.
Скопируйте код кода следующим образом:
импортировать java.util.HashMap;
импортировать java.util.Map;
общественный класс MemoryLeak {
public static void main(String[] args) {
Map<Key, String> map = new HashMap<Key, String>(1000);
интервал счетчика = 0;
в то время как (истина) {
// создает дубликаты объектов из-за плохого класса Key
map.put(new Key("dummyKey"), "value");
счетчик++;
если (счетчик % 1000 == 0) {
System.out.println("размер карты: " + map.size());
System.out.println("Свободная память после подсчета" + счетчик
+ " есть " + getFreeMemory() + "MB");
спать(1000);
}
}
}
// ключ внутреннего класса без hashcode() или Equals() — плохая реализация
статический класс Key {
частный строковый ключ;
открытый ключ (строковый ключ) {
this.key = ключ;
}
}
//задержка на заданный период в миллисекундах
public static void Sleep(long SleepFor) {
пытаться {
Thread.sleep(sleepFor);
} catch (InterruptedException e) {
е.printStackTrace();
}
}
// получаем доступную память в МБ
public static long getFreeMemory() {
return Runtime.getRuntime().freeMemory() / (1024 * 1024);
}
}
Результат следующий:
Скопируйте код кода следующим образом:
размер карты: 1000
Свободная память после отсчета 1000 составляет 4 МБ.
размер карты: 2000
Свободная память после отсчета 2000 составляет 4 МБ.
размер карты: 1396000
Свободная память после отсчета 1396000 составляет 2 МБ.
размер карты: 1397000
Свободной памяти после отсчета 1397000 — 2 МБ.
размер карты: 1398000
Свободная память после отсчета 1398000 составляет 2 МБ.
размер карты: 1399000
Свободная память после счетчика 1399000 составляет 1 МБ.
размер карты: 1400000
Свободная память после отсчета 1400000 составляет 1 МБ.
размер карты: 1401000
Свободная память после счетчика 1401000 составляет 1 МБ.
.....
.....
размер карты: 1452000
Свободная память после счетчика 1452000 равна 0 МБ.
размер карты: 1453000
Свободная память после счетчика 1453000 равна 0 МБ.
Исключение в потоке «основной» java.lang.OutOfMemoryError: пространство кучи Java
в java.util.HashMap.addEntry(HashMap.java:753)
в java.util.HashMap.put(HashMap.java:385)
в MemoryLeak.main(MemoryLeak.java:10)
Вопрос: Как решить описанную выше утечку памяти?
Ответ: Реализуйте методы Equals и HasCode класса Key.
Скопируйте код кода следующим образом:
.....
ключ статического класса {
частный строковый ключ;
открытый ключ (строковый ключ) {
this.key = ключ;
}
@Override
общественное логическое равенство (Object obj) {
если (объектный экземпляр ключа)
return key.equals(((Key) obj).key);
еще
вернуть ложь;
}
@Override
общественный int hashCode() {
вернуть ключ.hashCode();
}
}
.....
Повторное выполнение программы даст следующие результаты:
Скопируйте код кода следующим образом:
размер карты: 1
Свободная память после отсчета 1000 составляет 4 МБ.
размер карты: 1
Свободная память после отсчета 2000 составляет 4 МБ.
размер карты: 1
Свободная память после отсчета 3000 составляет 4 МБ.
размер карты: 1
Свободная память после отсчета 4000 составляет 4 МБ.
...
Свободная память после отсчета 73000 составляет 4 МБ.
размер карты: 1
Свободная память после отсчета 74000 составляет 4 МБ.
размер карты: 1
Свободная память после отсчета 75000 составляет 4 МБ.
Вопрос: Как в реальных сценариях обнаруживаются утечки памяти?
О: Получите идентификатор потока с помощью следующего кода.
Скопируйте код кода следующим образом:
C:/>джпс
5808Джпс
4568 Утечка Памяти
3860 Главная
Откройте jconsole через командную строку
Скопируйте код кода следующим образом:
C:/>jconsole 4568
Класс Key, реализующий hasCode и Equals, и диаграмма, которая его не реализует, выглядят следующим образом:
Нет утечки памяти:
Причина утечки памяти: