深入理解JVM——java内存区域与内存溢出异常

时间:2023-02-15 11:49:47

在java虚拟自动内存管理机制的帮助下,我们不再需要为每一个操作去写配套的delete/free代码,不容易出现内存泄漏问题,但是一旦出现,如果不了解虚拟机是什么使用内存的,那么排查错误将成为一件异常艰难的工作

运行时数据区域

深入理解JVM——java内存区域与内存溢出异常

(图片来自网络)后三个为线程隔离的



程序计数器

当前线程所执行的字节码的行号指示器,指明了执行到第几行代码,字节码解释器工作就是通过改变这个计数器的值来获取下一条需要执行的字节码,由于java虚拟机的多线程实现是通过线程轮流切换并分配处理器执行时间的方式来实现的,所以,为了线程切换后能恢复到正确的执行位置,每个线程都需要有自己独立的程序计数器


java虚拟机栈


经常有人把java内存分为堆内存和栈内存,实际上java的内存分配远比这复杂,而这所指的栈就是虚拟机栈


虚拟机栈描述了方法执行时的内存模型:方法执行时都会创建一个栈帧用来存放局部变量表、操作数栈、动态链接、方法出口,局部变量表存放了编译期可知的基本数据。每一个方法的执行就对应着一个栈帧在虚拟机栈中入栈和出栈


本地方法栈


类似于java虚拟机栈,虚拟机栈是java方法的内存模型,本地方法栈则执行native方法


java堆


java堆是java虚拟机所管理的最大的一块,所有线程共享,此内存区域的唯一目的就是存放对象实例(还有数组),java堆是垃圾收集器的主要区域


方法区

存放一个类的标示性信息,这部分应该结合类加载来看,当我们通过句柄访问类时,需要从堆中读取类的实例数据,还要从方法区中读取类的其他信息


Java内存管理和Java内存模型没有关系,两者是不同逻辑上的划分,如果硬要牵扯起来,内存模型中的主内存好比Java内存中的堆中的数据部分,线程内存对应栈帧中的数据区域