JVMの内存模型知多少?

内存模型

在这里插入图片描述


1.8同1.7比,最大的差别就是:元数据区取代了永久代。元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元数据空间并不存在虚拟机中,而是存在本地内存中。


  • JVM管理内存中最大的一块,是所有线程共享的一块内存区域,在虚拟机启动时创建。
  • 存放对象实例
  • 垃圾收集器主要管理的区域,由于收集器基本上采用分代垃圾收集算法,所以堆空间可细分为:新生代和老年代。

在这里插入图片描述

  • HotSpot JVM把年轻代分为了三部分:1个Eden区和2个Survivor区(分别叫from和to)。默认比例为8(Eden):1(一个Survivor)。
  • 一般情况下,新创建的对象都会被分配到Eden区(一些大对象特殊处理),这些对象经过第一次Minor GC后,如果仍然存活,将会被移到Survivor区。对象在Survivor区中每熬过一次Minor GC,年龄就会增加1岁,当它的年龄增加到一定程度时(默认15岁),就会被移动到年老代中。
  • 因为年轻代中的对象基本都是朝生夕死的(80%以上),所以在年轻代的垃圾回收算法使用的是复制算法,复制算法的基本思想就是将内存分为两块,每次只用其中一块,当这一块内存用完,就将还活着的对象复制到另外一块上面,复制算法不会产生内存碎片。
    在GC开始的时候,对象只会存在于Eden区和名为“From”的Survivor区,Survivor区“To”是空的。
  • 紧接着进行GC,Eden区中所有存活的对象都会被复制到“To”,而在“From”区中,仍存活的对象会根据他们的年龄值来决定去向。年龄达到一定值(年龄阈值,可以通过-XX:MaxTenuringThreshold来设置)的对象会被移动到年老代中,没有达到阈值的对象会被复制到“To”区域。
  • 经过这次GC后,Eden区和From区已经被清空。这个时候,“From”和“To”会交换他们的角色,也就是新的“To”就是上次GC前的“From”,新的“From”就是上次GC前的“To”。不管怎样,__都会保证名为To的Survivor区域是空的
    Minor GC会一直重复这样的过程,直到“To”区被填满,“To”区被填满之后,会将所有对象移动到年老代中。

元数据区(方法区,即永久代[1.7])

在这里插入图片描述
方法区(永久代)有一个本身设置的固定大小上限,无法进行动态调整。元数据区使用的是直接内存,受到物理本机可用内存限制。元数据区和永久代本质上都是方法区的实现。


虚拟机栈

在这里插入图片描述


本地方法栈

在这里插入图片描述


程序计数器

在这里插入图片描述


直接内存(非JVM范围内)

JDK1.4引入的NIO类,基于通道与缓存区的IO方式,可以直接使用Native函数库直接分配堆外内存,之后通过存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。避免在Java堆和Native堆之间来回复制数据,显著提升性能。


文章部分图片来自 https://blog.csdn.net/ztx114/article/details/79400789
文章内容参考自:https://blog.csdn.net/qq_34337272

猜你喜欢

转载自blog.csdn.net/Nerver_77/article/details/108736091
今日推荐