Java虚拟机内存模型的理解

这两天学习了jvm方面的知识,今天对内存模型做一个学习的总结。

在Java的运行时内存中主要分为两大块,线程共享区和线程独享区

①线程共享区

线程共享区顾名思义就是所有线程共享的一片内存区域,在这个区域中有Java的方法区和Java堆。

②线程独享区

线程独享区,也就是每个线程都有属于自己的那一份的内存区域。在线程独享区中有这个线程的虚拟机栈,本地方法栈和程序计数器

③方法区

方法区是线程共享区中的一块区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,是Java 虚拟机规范把方法区描述为堆的一个逻辑部分。既然它本质上也是属于堆内存,所以垃圾回收机也会去清理方法区,但是由于方法区中内存释放条件非常严格,所以垃圾回收器在这块区域中的回收效率比较低。

在方法区中还有一块被叫做 运行时常量池 的内存区域,用来存放一些类的常量,这些常量在类被加载之后就会放到这个运行时常量池中去。当然在程序实际运行时也能向这块内存区域中存放数据,例如String的intern() 方法,这个方法可以把我们通过new String()获得的一个放置在堆内存中的对象转移到运行时常量池中存放。

④Java堆

java堆是java内存模型中特别大的一块区域,是被所有线程共享的一块内存区域,在虚拟机启动时创建。用于存放几乎所有的对象实例,我们通过new关键字创建的对象都是存放在这个内存中。Java堆是垃圾回收机主要工作的区域,所以它的中的内存划分也很讲究,以8:1:1的比例分块以配合垃圾回收器工作(还可以细分)。

⑤虚拟机栈

虚拟机栈是属于线程独享区内存中的空间,每一个线程都有一个自己的虚拟机栈,它的生命周期与线程相同。虚拟机栈描述的是Java 方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧,栈帧用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。栈和堆最大的区别就是栈是单侧开口,先进后出形式的,所以这与我们在程序中顺序执行代码的逻辑非常吻合,比如在main方法中,我调用了一个ArrayList对象的add方法,这时java虚拟机就会为add方法创建一个栈帧并把它放入栈中,当add方法中的代码执行完毕后,add方法的栈帧出栈。当然在使用递归函数的时候,使用不当就会不停的入栈,这时当栈的内存不够用了就会抛出异常。

⑥本地方法栈

本地方法栈的原理和虚拟机栈是一样的,只不过虚拟机栈是用来描述java方法的,本地方法栈是用来描述本地方法的。而且在一些虚拟机中(HotSpot虚拟机)中本地方法栈和虚拟机栈使用的是同一个栈。

⑦程序计数器

程序计数器也是每个线程都有一个的,它占据非常的一片内存区域,用来记录线程执行的行号,当然不是12345这种形式。我们在线程中所使用的顺序逻辑结构,条件判断逻辑结构,循环逻辑结构都有它的功劳,这也就是为什么while循环每次循环完毕一遍再循环时能跳到上面几行再次执行代码,都是程序计数器在帮助我们做这些工作。它保证我们的代码能够井井有条的按照开发者的思路进行执行。

 

总结

之前有人问起我java内存模型,我只会说分为堆和栈,当深入了解它之后才发现不单单是这样,我们平时所说的java内存的堆和栈,堆指的就是java堆,栈指的虚拟机栈,这两个部分是最关键最显眼的部分,但是其他的区域也是必不可少的。

 

本文只是笔者自己的理解,有什么错误还请大家指出。

参考资料:《深入理解java虚拟机》 ps:这本书真的是特别的棒!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值