1.程序计数器:当前线程的正在执行的字节码指示器
2.虚拟机栈和本地方法栈:虚拟机栈存储局部变量表(包括方法入参和布局变量)、操作数栈、方法返回地址(调用者的栈帧,包括return返回和异常返回)等
3.堆:为几乎所有对象实例分配内存的区域
4.方法区:用于存储已被虚拟机加载的类信息、常量(static final)、静态变量(static)、即时编译器编译后的代码,是JVM规范中的一个逻辑概念,具体存放在哪里,由虚拟机实现。非堆
5.直接内存:使用操作系统的本地函数库分配的非堆内存,再通过Java的DirectByteBuffer对象引用这块内存
线程共享的区域:
堆、方法区、直接内存
线程隔离的区域:
程序计数器和栈
线程的栈帧大小超出了jvm的设置的栈容量(-Xss可以设置虚拟机栈的容量,在HotSpot虚拟机中,不区分虚拟机栈和本地方法栈,所以在HotSpot虚拟机中-Xss设置的是栈大小),最常见的情况就是程序出现了错误的递归,导致在一个线程中栈帧的深度过大
JVM栈最大容量参数:-Xss2M
JVM堆参数配置:
在java1.6中的HotSpot虚拟机中,方法区用永久代实现。当永久代占用的内存大于JVM参数的永久代最大值时出现内存溢出
Java1.6-1.7的JVM永久代参数配置:
最小永久代:-XX:PermSize=500m 最大永久代:-XX:MaxPermSize=1000m
Java1.8中利用元空间实现方法区,永久代的概念被移除了(-XX:MaxPermSize失去了意义),使用参数:
最大元空间设置:-XX:MaxMetaspaceSize
直接内存容量大小默认与Java堆得最大值(-Xmx)相同,可以通过参数:-XX:MaxDirectMemorySize=1G指定
创建的线程过多,亦或是JVM线程栈参数过大,导致操作系统无法继续创建新的线程,会出现OutOfMemoryError
堆+线程个数*栈帧容量+方法区+直接内存+操作系统占用内存
参数配置:-Xmx + threadCount*-Xss+(-XX:MaxPermSize 或者 -XX:MaxMetaspaceSize)+-XXMaxDirectMemorySize
OutOfMemoryError和StackOverflowError
原文:https://www.cnblogs.com/boboshenqi/p/12588838.html