Введение
В этом лабе вы научитесь эффективно использовать память Java Heap, чтобы избежать ошибок связанных с памятью Java Heap.
Ошибка памяти Java Heap
Ошибка памяти Java Heap возникает, когда виртуальная машина Java (JVM) не может выделить память для объектов в памяти Java Heap. Плохие практики программирования, утечки памяти, сторонние библиотеки могут привести к этой ошибке.
Код:
import java.util.ArrayList;
public class JavaHeapMemoryError {
public static void main(String[] args) {
ArrayList<Object> list = new ArrayList<Object>();
while (true) {
Object o = new Object();
list.add(o);
}
}
}
Для того, чтобы увидеть ошибку в действии, скомпилируйте и запустите код в терминале:
javac JavaHeapMemoryError.java
java -Xmx512m JavaHeapMemoryError
Программа пытается выделить как можно больше памяти, непрерывно создавая объекты и добавляя их в ArrayList, пока JVM не выбросит ошибку OutOfMemoryError. Параметр -Xmx задает максимальный объем памяти, выделяемой JVM.
Причины ошибки памяти Java Heap
Ошибка памяти Java Heap возникает в основном из-за плохих практик программирования, утечки памяти и сторонних библиотек. Чтобы предотвратить ее, мы должны избегать бесконечных циклов, объектов, которые долго хранятся без использования и не очищаются, и предоставлять неиспользуемые объекты сборщику мусора.
Код:
public class JavaHeapMemoryError {
public static void main(String[] args) {
int[] arr = new int[100000000];
for(int i=0; i<arr.length; i++){
arr[i] = i;
}
System.out.println("Memory allocated");
}
}
Для того, чтобы увидеть код в действии, скомпилируйте и запустите код в терминале:
javac JavaHeapMemoryError.java
java -Xmx256m JavaHeapMemoryError
Утечка памяти
Утечка памяти возникает, когда неиспользуемый объект в памяти кучи по-прежнему имеет действительные ссылки и не может быть удален сборщиком мусора. Чтобы избежать утечек памяти, все открытые ресурсы должны быть закрыты с использованием блока finally.
Код:
public class MemoryLeak {
static ArrayList<String> arrList = new ArrayList<String>(500);
public static void main(String args[]) {
for (int i = 0; i < 500; i++) {
arrList.add("Element " + i);
}
arrList = null;
}
}
Для того, чтобы увидеть код в действии, скомпилируйте и запустите код в терминале:
javac MemoryLeak.java
java -Xmx256m MemoryLeak
Превышенное использование финализаторов
Превышенное использование финализаторов может привести к ошибке памяти Java Heap, потому что классы, содержащие метод finalize, не имеют своих пространств объектов, освобождаемых в процессе сборки мусора.
Код:
public class ExcessiveFinalizer {
public void finalize() {
//Do some cleanup
}
public static void main(String[] args) {
ArrayList<ExcessiveFinalizer> list = new ArrayList<ExcessiveFinalizer>();
while (true) {
list.add(new ExcessiveFinalizer());
}
}
}
Для того, чтобы увидеть код в действии, скомпилируйте и запустите код в терминале:
javac ExcessiveFinalizer.java
java -Xmx256m ExcessiveFinalizer
Увеличить память Java Heap
Если ошибка была вызвана недостаточностью выделенной для JVM памяти, мы можем увеличить доступное пространство памяти кучи, увеличив предел, установленный командой -Xmx.
Код:
public class IncreaseHeapMemory {
public static void main(String[] args) {
Integer[] outOfMemoryArray = new Integer[Integer.MAX_VALUE];
}
}
Для того, чтобы увидеть код в действии, скомпилируйте и запустите код в терминале:
javac IncreaseHeapMemory.java
java -Xmx8g IncreaseHeapMemory
Резюме
В этом практическом занятии вы узнали, как эффективно управлять памятью кучи для ваших Java-приложений, чтобы избежать ошибок памяти Java Heap. Мы изучили различные методы предотвращения ошибок, такие как избегание неэффективных циклов, закрытие неиспользуемых ресурсов и предоставление неиспользуемых объектов сборщику мусора пораньше. Наконец, если недостаточность памяти кучи была причиной ошибки, мы увеличили предел с использованием команды -Xmx.



