深入理解JAVA虚拟机(三)内存分配与回收机制

 2019-12-22 10:50  阅读(1066)
文章分类:JVM

一.JAVA内存

Java的内存通常分为堆内存和非堆内存,堆内存由 Java 对象使用,非堆内存则用于存放 JNI、Java 线程对象等非 Java 数据。

2019120001350\_1.png

![《深入理解JAVA虚拟机(三)内存分配与回收机制》][JAVA]

![《深入理解JAVA虚拟机(三)内存分配与回收机制》][JAVA]

二.垃圾收集

2019120001352\_2.png

JVM Generational Collecting(分代)原理是这样的:把对象分为年青代(Young)、年老代(Tenured)、持久代(Perm),对不同生命周期的对象使用不同的算法。(基于对对象生命周期分析)

  1. Young(年轻代)

年轻代分三个区。一个 Eden 区,两个 Survivor 区。大部分对象在 Eden 区中生成。 幸存者 0 区(Survivor 0 space)和幸存者 1 区(Survivor1 space):当伊甸园的空间用完时,程序又需要创建对象;此时 JVM 的垃圾回收器将对伊甸园区进行垃圾回收,将伊甸园区中的不再被其他对象所引用的对象进行销毁工作。同时将伊甸园中的还有其他对象引用的对象移动到幸存者 0 区。幸存者 0 区就是用于存放伊甸园垃圾回收时所幸存下来的 JAVA 对象。当将伊甸园中的还有其他对象引用的对象移动到幸存者 0 区时,如果幸存者 0 区也没有空间来存放这些对象时,JVM 的垃圾回收器将对幸存者 0 区进行垃圾回收处理,将幸存者 0 区中不在有其他对象引用的 JAVA 对象进行销毁,将幸存者 0 区中还有其他对象引用的对象移动到幸存者 1 区。幸存者 1 区的作用就是用于存放幸存者 0 区垃圾回收处理所幸存下来的JAVA 对象。

2.Tenured**(年老代)**

年老代存放从年轻代存活的对象。一般来说年老代存放的都是生命期较长的对象。

3.Perm(持久代)

用于存放静态文件,如今 Java 类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些 class,例如 Hibernate 等, 在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类。持久代大小通过-XX:MaxPermSize=进行设置。

举个例子:当在程序中生成对象时,正常对象会在年轻代中分配空间,如果是过大的对象也可能会直接在年老代生成(据观测在运行某程序时候每次会生成一个十兆的 空间用收发消息,这部分内存就会直接在年老代分配)。年轻代在空间被分配完的时候就会发起内存回收,大部分内存会被回收,一部分幸存的内存会被拷贝至 Survivor 的 from 区,经过多次回收以后如果from区内存也分配完毕,就会也发生内存回收然后将剩余的对象拷贝至to区。等到 to 区也满的时 候,就会再次发生内存回收然后把幸存的对象拷贝至年老区。

通常我们说的 JVM 内存回收总是在指堆内存回收,确实只有堆中的内容是动态申请分配的,所以以上对象的年轻代和年老代都是指的 JVM 的 Heap 空间,而持久代则是之前提到的 Method Area,不属于 Heap。

补充:http://blog.csdn.net/wzy\_1988/article/details/47722649

[JAVA]:

点赞(0)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> 深入理解JAVA虚拟机(三)内存分配与回收机制

相关推荐