- 程序计数器:以后线程所执行的字节码的行号指示器。(内存较小,惟一一个有规定任何 OutOfMemoryError 状况的区域。)
- Java 虚拟机栈(是 Java 办法 执行的线程内存模型:每个办法被执行的时候,Java 虚拟机都会同步创立一个栈帧[1](Stack Frame)用于存储局部变量表、操作数栈、动静连贯、办法进口等信息)(常说的栈指虚拟机栈中局部变量表局部)
2.1 局部变量表:根本数据类型,句柄等
2.2 StackOverflowError:线程申请的栈深度 > 虚拟机所容许的深度
2.3 OutOfMemoryError: 若 Java 虚拟机栈容量能够动静扩大,当栈扩大时无奈申请到足够的内存 - 本地办法栈:为虚拟机 本地办法 服务(同上:StackOverflowError 和 OutOfMemoryError)
- 堆(线程共享):虚拟机启动时创立,寄存对象实例,垃圾收集器治理的内存区域(参数 -Xmx 和 -Xms 设定大小,可能呈现 OutOfMemoryError)
4.1 新生代
4.2 老年代
4.3 永恒代
5. 办法区:(线程共享)存储已被虚拟机加载的类型信息、常量、动态变量、即时编译器编译后的代码缓存等(OutOfMemoryError)
运行时常量池:(类加载时)用于寄存编译期生成的各种字面量与符号援用
6. 间接内存:(OutOfMemoryError)
对象分配内存流程如下
对象存储布局如下:
- 对象头
1.1 存储对象本身的运行时数据(哈希码(HashCode)、GC 分代年龄、锁状态标记、线程持有的锁、偏差线程 ID、偏差工夫戳)
1.2 类型指针
1.3 数组(记录数组长度) - 实例数据:对象真正存储的无效信息(存储程序会受到虚拟机调配策略参数(-XX:FieldsAllocationStyle 参数)和字段在 Java 源码中定义程序的影响。)
+XX:CompactFields:子类中较小的会插入父类较大的
- 对齐填充
栈:寄存援用地址 -》堆(对象实例数据和对象类型数据指针)-》办法区(对象类型数据)
呈现 OOM 解决形式如下:(Eclipse Memory Analyzer)
1 首先剖析是内存透露还是内存溢出
2 若为内存透露,则剖析 GC Roots 援用链信息
3 内存溢出(设置 -Xmx 与 -Xms)代码上查看
是否存在某些对象生命周期过长、持有状态工夫过长、存储结构设计不合理等状况,尽量减少程序运行期的内存耗费。
栈容量设置:-Xss
JDK1.6 之前:
-XX:PermSize 和 -XX:MaxPermSize(永恒代(常量池中:本地办法栈中),之后在元空间(堆))
JAVA1.8:
-XX:MaxMetaspaceSize:元空间最大值
-XX:MetaspaceSize:元空间的初始空间大小,以字节为单位,达到该值就会触发垃圾收集进行类型卸载,同时收集器会对该值进行调整:如果开释了大量的空间,就适当升高该值;如果开释了很少的空间,那么在不超过 -XX:MaxMetaspaceSize(如果设置了的话)的状况下,适当进步该值
-XX:MinMetaspaceFreeRatio:
间接内存溢出:OOM 是内存很小
-XX:MaxDirectMemorySize(默认 java 堆的最大值):