JVM 自动内存管理机制——Java内存区域与内存溢出异常
(一)运行时数据区
程序计数器:存放当前线程所执行的字节码的指令地址(可以理解为执行的行号指示器)。
虚拟机栈:存放当前线程(java方法)的局部变量表、操作数栈、动态链接、方法出口等信息(当前线程创建 的一个栈帧)。
本地方法栈:存放本地方法的局部变量表、操作数栈、动态链接、方法出口等信息。
堆:所有线程共享的一块内存区域,在虚拟机启动时创建,用来存放几乎所有的对象实例。
方法区:所有线程共享,用户存储虚拟机家在的类信息、常量、静态变量、即时编译器编译后的代码等数据。
运行时常量池:方法区的一部分,用户存放编译期生成的各种字面量和符号引用。
(二)内存溢出(OutOfMemoryError)
Java堆溢出:创建实例对象过多并且垃圾回收机制未及时清除对应的对象,导致内存占用达到最大堆容量时,再创建实例申请内存就会出现堆溢出。
虚拟机和本地方法栈溢出:线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常;虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。
方法区和运行时常量池溢出:运行时产生大量的类去填满方法区,达到其最大的容量时会产生溢出
本机内存直接溢出:机器上的内存被使用完时产生溢出。
小结:透过了解虚拟机的内存分配,在实际操作过程中可以去排查对应的内存溢出问题,本文主要介绍了产生内存溢出的几种可能性,具体的问题可以参考对照,若有不对之处欢迎多多指教!