Java内存模型

这段时间重新拜读了《深入理解Java虚拟机》这本书,对于java内存模型又有了新的认识和收获,记录一下!

先来看看我们常说的java内存模型吧,不啰嗦,直接上图。

1.程序计数器

程序计数器是一块较小的内存空间,它可以看做是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里面,字节码解释器工作时就是通过改变这个行号计数器的值,从而决定下一条执行哪一行字节码指令。

那么,问题来了,为什么需要这个行号指示器呢?学习过操作系统的童鞋都应该听过“时间碎片”这个概念,对于同一个CPU来讲,同一时刻,只能处理一个进程中的、某个线程中的指令。这是因为cpu会将执行时间“切成”极小的时间碎片分配给进程,进程中又有线程,时间碎片的细腻程度由cpu频率决定。。。。(艾玛赶脚有点扯远了,就此打住吧,不熟悉的同学请自行Google哈)。

为了能在线程切换后可以恢复到正确的执行位置,每个线程都必须要有一个独立的程序计数器,各个线程之间计数器互不影响,独立存储,因此程序计数器被设计成线程私有的内存区域。

需要说明的是:程序计数器仅仅用来记录字节码行号,并不会出现OOM,因此它是唯一一个在Java虚拟机规范中没有规定任何OOM(OutOfMemoryErrror)情况的区域。

2.Java虚拟机栈

与程序计数器一样,Java虚拟机栈也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的时候都会同时创建一个栈帧,栈它是用于支持续虚拟机进行方法调用和方法执行的数据结构。对于执行引擎来讲,活动线程中,只有栈顶的栈帧是有效的,称为当前栈帧,这个栈帧所关联的方法称为当前方法,执行引擎所运行的所有字节码指令都只针对当前栈帧进行操作。栈帧用于存储局部变量表、操作数栈、动态链接、方法出口信息等。在编译程序代码时,栈帧中需要多大的局部变量表、多深的操作数栈都已经完全确定了,并且写入了方法表的 Code 属性之中。因此,一个栈帧需要分配多少内存,不会受到程序运行期变量数据的影响,而仅仅取决于具体的虚拟机实现。

3.本地方法栈

该区域与虚拟机栈所发挥的作用非常相似,只是虚拟机栈为虚拟机执行 Java 方法服务,而本地方法栈则为使用到的本地操作系统的Native方法服务,可以理解成 C++类库。

4.Java堆

堆区是理解Java GC机制最重要的区域,没有之一。在JVM所管理的内存中,堆区是最大的一块,堆区也是Java GC机制所管理的主要内存区域,堆区 由所有线程共享 ,在虚拟机启动时创建。堆区的存在是为了 存储对象实例 ,原则上讲,所有的对象都在堆区上分配内存(不过现代技术里,也不是这么绝对的,也有栈上直接分配的)。

5.方法区

方法区也是各个线程共享的内存区域,它用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。方法区域又被称为“永久代”,当然这仅仅对于 HotSpot 来讲,因为有些虚拟机中并不存在永久代的概念,譬如IBM J9、BEA JRockit。

6.运行时常量

运行时常量池(Runtime Constant Pool)是方法区的一部分,用于存储编译期就生成的字面常量、符号引用、翻译出来的直接引用(符号引用就是编码是用字符串表示某个变量、接口的位置,直接引用就是根据符号引用翻译出来的地址,将在类链接阶段完成翻译);运行时常量池除了存储编译期常量外,也可以存储在运行时间产生的常量(比如String类的intern()方法,作用是String维护了一个常量池,如果调用的字符“abc”已经在常量池中,则返回池中的字符串地址,否则,新建一个常量加入池中,并返回地址)。

7.直接内存

直接内存并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域。但是这部分内存也被频繁使用,而且也可能导致OOM异常。比如说一台服务器总共有8G内存,JVM占用2G,剩下的6G就是直接内存。

从JDK1.4开始,引入了NIO(有人称之为新IO,也有人称之为非阻塞IO,随你怎么叫啦)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O方式,它可以使用Native方法直接分配对外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆中和Nativa堆中来回的复制数据。

由于直接内存收到本机器内存的限制,所以也可能出现OutOfMemoryError的异常。

以上就是关于Java虚拟机的内存模型的学习总结,笔者尽量以比较通俗易懂的方式来表达,写的比较粗糙,望见谅~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值