Java内存管理:深入Java内存区域

运行数据区图

这里写图片描述

程序计数器

是一块较小的内存空间,就是用来放置每一个线程所执行的字节码的行号,就是用来保存每个线程执行到了那里( 操作系统时间片轮转),等下一次改线程来的时候会接着上次执行的地方,继续执行。像分支、循环、跳转、异常处理等都需要依赖这个功能来处理。每个线程都有自己的程序计数器,互不影响,这是线程所私有的。如果线程正在执行的是一个native方法,那么这个计数器的值为空。

虚拟机栈

也是线程所私有的,因此生命周期也与线程相同,我的理解是,线程在执行期间产生的变量等操作,例如执行方法的时候会创建一些局部变量,就存放在这里,随着方法的执行结束,也就是对应这栈帧在虚拟机栈中入栈到出栈的过程。局部变量所需要的内存空间在编译阶段完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部是完全确定的。因此如果线程请求的栈深度大于虚拟机允许的深度时候,就会报出StackOverflowError异常。

本地方法栈

本地方法栈与虚拟机栈是类似的,只不过本地方法栈保存的是执行的native方法服务。

所有线程所共享的一个区域,此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。因此java内存垃圾回收的主要区域也是这个内存区域,GC堆。java堆又划分为新生代和老年代,新生代又分为Eden空间、From Survivor空间、To Survivor空间等

方法区

各个线程所共享的区域 ,用于存储类的信息、常量、静态变量等

运行时常量池

也是方法区的一部分,用来存放编译期圣光城的各种字面量和符号引用,用的比较多的是String类的intern()方法

直接内存

该块区域并不是虚拟机运行时数据区域的一部分,也不是虚拟机规范定义的内存区域,是本机的内存。因为jdk1.4中新加入了NIO类,引入了一种基于通道与缓冲区的I/O方式,他可以使用native函数库直接分配堆外内存,然后通过一个存储在java堆中的DirectByBuffer对象作为这块内存的引用操。这样能在一些场景中显著提高性能,避免了在java堆和native堆中来回复制数据。

猜你喜欢

转载自blog.csdn.net/zhouchaoqiang/article/details/78248665