![](https://img.haomeiwen.com/i11772136/cadd36dbd42eca76.png)
一、程序计数器:不会抛出任何异常
线程如果执行的是Java方法,该计数器是虚拟机字节码指令的地址;
线程如果执行的是Native方法,改计数器的值是零。
二、JVM方法栈:Java方法的内存模型。
每个线程独自占有一个方法栈,该栈的生命周期与线程相同。
栈中的元素是栈帧,其中存储局部变量表和方法出口等数据。入栈和出栈表示Java方法的调用和退出。
两种异常:
1)OutOfMemoryError:unable to create new native thread. 线程数量增加,导致内存不够,无法为新线程分配内存。
还有一个原因也会抛出异常,就是OS对线程数量的限制,命令是ulimit。这个原因在UPOS项目中遇到过。
2)StackOverflowError:线程调用方法的深度过深,超过了JVM的限制,此异常常见于递归。
-Xss可设置每个线程的JVM栈的大小。如果减小这个值,那么线程的数量可以增多。增大这个值方法调用深度也会增加。
三、本地方法栈:为执行本地方法服务。也会抛出OutOfMemoryError和StackOverflowError。
HotSpot虚拟机已经将本地方法栈和JVM方法栈合二为一。
四、堆(Heap)。所占内存最大,因为这是存放对象的主要空间。
分为新生代和老年代。
新生代包括eden区和两个survivor区。
异常:OutOfMemoryError
-Xms20m -Xmx20m 可以设置堆的最小值和最大值
五、方法区(持久区) JDK8以后消失
存放类的元信息
异常:OutOfMemoryError
UPOS项目加载规则文件(file.drl),每个规则被转化成一个Class,导致方法区空间不够。
六、运行时常量池
class文件被加载时,其中的常量将会被加载到常量池中,
常量不仅在编译时产生,可以在运行时产生。比如String.intern(),如果常量池中的常量不断增多,也会引起OutOfMemoryError.
在JDK6之前存放在方法区,之后存放在堆中。
七、Metaspace:元空间,JDK8以后产生,存放类元信息
元空间不在虚拟机中,而是在本地内存中。
-XX:MetaspaceSize -XX:MaxMetaspaceSize
网友评论