一、内存分配与回收
JVM是Java虚拟机的缩写,是Java语言最重要的一部分,是一个虚拟的计算机。当Java程序运行时,JVM会为程序分配一块内存,这块内存被称为JVM的堆内存。当Java程序创建对象时,编译器会把变量名解析为对对象的引用。JVM会通过循环遍历可达对象的链表,在你不需要使用这些对象时回收它们占用的内存。
二、JVM分区与GC算法
JVM把堆分成了新生代和老年代两个区域。新生代主要用于存放新创建的对象,老年代用于存放已经存活了一段时间的对象。JVM使用不同的垃圾回收算法来回收不同的分区空间。
三、JVM分区详解
在JVM里,堆分为两块区域:新生代和老年代。新生代又被分为两块区域:Eden空间和两块Survivor空间。新创建的对象首先会被分配到Eden空间中,当Eden空间满时,JVM的垃圾回收器会扫描这些存活的对象,将它们复制到一个Survivor空间中。Survivor空间也被JVM分为了两个区域。垃圾回收器会不断地扫描这些对象,直到它们被放到老年代。
老年代主要用于存储一些生命周期比较长的对象,比如静态变量和常量池。老年代中存储的对象比新生代中存储的对象生命周期要长,JVM使用了不同的回收算法来处理老生代的垃圾回收。
四、新生代分区详解
新生代内存分为Eden区、Survivor区0和Survivor区1三个部分。其中Eden区主要用于存放新创建的对象,Survivor区用于存放从Eden区中复制过来并经过了一次GC仍然存活的对象。这些对象将会在Survivor的两个空间中来回移动,最终被选出即将要晋升到老生代的对象放置在Survivor区1中。
public class ObjectDemo{ public static void main(String[] args){ ObjectDemo obj1, obj2, obj3; obj1 = new ObjectDemo(); obj2 = new ObjectDemo(); obj3 = new ObjectDemo(); System.out.println("ObjectDemo 创建了3个实例"); } }
五、老生代分区详解
老生代存储的对象生命周期比新生代中的对象要长得多,这里主要存放一些生命周期比较长的对象,比如静态变量和常量池。老年代的垃圾回收一般是使用标记-清除算法,并且在清除后会产生大量的内存碎片。为了减少内存碎片的产生,JVM将老生代分为了不同的区域,每个区域内都是满足连续内存的。当某个区域内的内存使用完时,会把其中的存活对象移到其他区域中,并且在这个过程中会进行压缩,消除内存碎片问题。
public class ObjectDemo{ public static void main(String[] args){ ObjectDemo obj1 = new ObjectDemo(); ObjectDemo obj2 = new ObjectDemo(); System.gc(); System.out.println("第一次gc完成"); ObjectDemo obj3 = new ObjectDemo(); ObjectDemo obj4 = new ObjectDemo(); obj3 = null; obj4 = null; System.gc(); System.out.println("第二次gc完成"); } }
六、永久代与元空间
在JDK8之前,Java虚拟机的永久代是用于存储虚拟机自身的类元数据的区域,并且这个区域是非常少被使用到的。而在JDK8之后,永久代被彻底移除了,取而代之的是元空间,它是使用本地内存来存储类元数据,因为它不再是虚拟机内部的一块区域了。元空间内存使用的变化和永久代有些不同,只需要设置一个大小上限就可以了。
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/191130.html