는 바이트코드 해석기가 실행해야 하는 바이트코드 명령어를 선택하는 데 사용됩니다. 각 스레드에는 독립적인 프로그램 카운터가 있으며 스레드는 서로 영향을 미치지 않습니다. 스레드가 Java 메소드를 실행하는 경우 이 카운터는 네이티브 메소드를 실행하는 경우 실행 중인 가상 머신 바이트코드 명령의 메모리 주소를 기록합니다. 카운터가 정의되지 않았습니다. 이 영역은 JVM 사양에서 유일하게 OOM이 존재하지 않는 영역입니다.
컴파일러가 알고 있는 다양한 기본 데이터 유형(boolean, byte, char)이 저장됩니다. , short, int, float, long, double), 객체 적용(참조). 64비트 double 및 long은 2개의 슬롯을 차지합니다. 메모리 공간은 메소드를 입력할 때 할당해야 하는 로컬 변수 공간이 완전히 결정됩니다. -Xss
예외:
StackOverflowError 스택 깊이가 가상 머신에서 허용하는 깊이보다 큽니다.
OOM 가상 머신 스택을 동적으로 확장할 수 있는 경우(대부분의 Java 가상 머신은 동적으로 확장할 수 있지만 Java 가상 머신 사양에서는 고정 길이 가상 머신 스택), 확장이 충분한 메모리를 적용할 수 없는 경우
단일 스레드에서 스택 프레임이 너무 크거나 가상 머신 스택 용량이 너무 작은 경우, 메모리를 할당할 수 없는 경우 , 가상 머신은 모두 StackOverflowError
/** * VM Args:-Xss128k * * stack length:2402 Exception in thread "main" java.lang.StackOverflowError */ public class JavaVMStackSOF { private int stackLength = 1; public void stackLeak() { stackLength++; stackLeak(); } public static void main(String[] args) throws Throwable { JavaVMStackSOF oom = new JavaVMStackSOF(); try { oom.stackLeak(); } catch (Throwable e) { System.out.println("stack length:" + oom.stackLength); throw e; } } }
를 발생시킵니다. 테스트가 단일 스레드에 국한되지 않는 경우 스레드를 지속적으로 설정하면 메모리 오버플로 예외가 발생할 수 있습니다. 그러나 이렇게 생성된 메모리 오버플로 예외는 점유 공간이 충분히 큰지 여부와는 관련이 없습니다. 정확하게 말하면, 이 경우 각 스레드의 스택에 할당된 메모리가 클수록 메모리 오버플로 예외가 발생하기 쉽습니다. .
운영 체제에서 각 프로세스에 할당하는 메모리는 제한되어 있기 때문에 예를 들어 32비트 창은 2GB로 제한됩니다. 이 테스트는 많은 수의 스레드를 생성하여 수행됩니다. 각 스레드는 스택 메모리를 점유하고 많은 양의 메모리를 할당하므로 시스템의 메모리가 부족해집니다. 자동으로 확장할 수 없도록
/** * VM Args:-Xss2M (这时候不妨设大些) * * java.lang.OutOfMemoryError:unable to create new native thread */ public class JavaVMStackOOM { private void dontStop() { while (true) { } } public void stackLeakByThread() { while (true) { Thread thread = new Thread(new Runnable() { @Override public void run() { dontStop(); } }); thread.start(); } } public static void main(String[] args) throws Throwable { JavaVMStackOOM oom = new JavaVMStackOOM(); oom.stackLeakByThread(); } }
은 가상 머신 스택과 유사하지만 하나는 Java 메소드를 실행하는 가상 머신이고 다른 하나는 Native 메소드를 실행한다는 점만 다릅니다
예외 상황:
StackOverflowError 스택 깊이가 가상 머신에서 허용하는 깊이보다 큽니다
OOM
A 스레드가 공유하는 메모리 영역은 메모리 재활용의 관점에서 기본적으로 세대별 수집 알고리즘을 채택하므로 신세대와 구세대로 구분됩니다. 좀 더 세부적으로는 Eden 공간, From Survivor 공간, To Survivor 공간 등으로 나눌 수 있습니다. -Xmx -Xms 힙 공간 크기 제어
예외:
1.OOM 힙을 확장할 수 없는 경우
/** * VM Args:-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError * * java.lang.OutOfMemoryError: Java heap space */ public class HeapOOM { static class OOMObject { } public static void main(String[] args) { List<OOMObject> list = new ArrayList<OOMObject>(); while (true) { list.add(new OOMObject()); } } }
스레드 간에 공유됩니다. 가상 머신에서 로딩한 클래스 정보, 상수, 정적 변수, 인스턴트 에디터로 컴파일한 코드 등의 데이터를 저장하는 것을 HotSpot 가상 머신의 불멸의 세대라 할 수 있습니다.
런타임 상수는 1.6 및 이전 버전에서 메서드 영역의 일부였습니다(String.intern()이 상수 풀을 동적으로 추가함) -XX:MaxPermSize는 크기를 제어합니다. JDK1.7 이상 버전에서는 Java 힙에서 메모리 조각이 열립니다.
예외 상황:
OOM
/** * 需要在JDK1.6上才能复现,JDK1.7及之后版本的JVM已经将运行时常量池从方法区中移了出来,在Java 堆(Heap)中开辟了一块区域存放运行时常量池。 * 在JDK1.7上运行的效果则会一直执行,直到堆内存使用完毕 * VM Args:-XX:PermSize=10M -XX:MaxPermSize=10M * * java.lang.OutOfMemoryError:PermGen space */ public class RuntimeConstantPoolOOM { public static void main(String[] args) { // 使用List保持着常量池引用,避免Full GC回收常量池行为 List<String> list = new ArrayList<String>(); // 10MB的PermSize在integer范围内足够产生OOM了 int i = 0; while (true) { list.add(String.valueOf(i++).intern()); } } }rrree
NIO는 Native 함수 라이브러리를 사용하여 외부 메모리를 직접 할당한 다음 이 메모리에 대한 참조로 Java 쌍에 저장된 DirectByteBuffer 개체를 통해 작동할 수 있습니다. 머신의 물리적 메모리에 의해 제한되며 -XX:MaxDirectMemorySize를 통해 지정할 수 있습니다. 지정하지 않을 경우 기본값은 Java 힙 최대값(-Xmx)과 동일합니다.
예외:
1 .OOM
아아아아위 내용은 JVM의 각 영역의 목적에 대한 자세한 설명과 잠재적인 예외에 대한 코드 예제의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!