欢迎光临车床网站,为您提供精密加工全套工艺生产线

[北京二手机床回收]垃圾回收,从JVM开始

作者:以沫      发布时间:2021-04-23      浏览量:0
关于垃圾回收分类,相信大家还是比较有感

关于垃圾回收分类,相信大家还是比较有感触的。自今年5月1日起,北京公布了《北京市生活垃圾管理条例》,单位和居民不执行垃圾分类将面临处罚。在垃圾回收条例中,从之前的可回收垃圾、不可回收垃圾,升级为把垃圾明确分为了 厨余垃圾、可回收垃圾、有害垃圾、其它垃圾 四大类。每个人都要养成垃圾分类、垃圾回收的意识。事实上在互联网程序的世界里也存在垃圾回收的概念,那便是我们中大型应用开发必用、使用的应用程序占比超过80%的开发语言 JAVA 了。

所有的Java程序都是运行在JVM(JAVAVirtualMachine,Java虚拟机)中的,在Java程序运行时,JVM会为每个对象创建一块内存,并维护管理这块内存。现在最新的JDK版本(JAVADevelopmentKit,Java开发工具包,JVM运行在JDK上)已到JDK13及以上了,因此通过下图(JDK1.8)可以来看看JVM的内存模型。在内存模型中包含堆、虚拟机栈本地方法栈、方法区、程序计数器等等元素,堆主要用于存放所有的对象实例,实例创建后在此分配内存;虚拟机栈是Java方法执行的内存模型,每个Java方法在执行时都会同时创建一个栈帧,来存储局部变量表、操作栈、动态链接、方法返回地址等;本地方法栈则是服务于虚拟机使用到的Native方法;方法区是存储虚拟机加载的元数据信息;元数据区主要是存储方法名、方法变量等元数据信息;程序计数器主要是指明当前线程所执行的字节码。因为Java对象主要在Heap堆区中运行,因此总的来说,JVM管控的内存就是Heap内存、Non-Heap内存。

一个Java程序的执行如下图所示,通过编译成class文件,调用JVM的类加载子系统,在内存空间中创建对象、执行对象,执行结束后,进行对象的内存回收,也就是垃圾回收(GarbageCollection)。

所谓垃圾回收 , 指的是JVM释放掉那些没有引用对象做占用的内存空间,给新的对象使用 。 参照垃圾分类的思想,在JVM中也会根据对象的存活周期将对象分代,包含年轻代、老年代、持久代,通过内存分代,可以更好的执行垃圾回收,提高效率。年轻代用来存储最近新创建的对象,在年轻代中存在的对象死亡是非常快的,为了提高年轻代中的垃圾回收效率,年轻代又会划分出Eden、Survivorfrom、Survivorto三个区域,年轻代的垃圾回收成为MinorGC;老年代用来存储存活很久的对象,老年代的垃圾回收成为MajorGC;持久代存储JVM运行时的需要的Java库的类和方法,一般由Java厂商指定,在JDK1.8之后,改名为metaspace元空间。

在JVM中内存回收过程大概如下:对象在年轻代EdenSpace创建,当EdenSpace内存空间满的时候,垃圾回收器就把所有在EdenSpace中的对象都扫描一次,把有效的对象复制到第一个SurvivorSpace(即Survivorfrom),无效的对象所占用的空间进行释放。当EdenSpace再次变满的时候,把EdenSpace中有效的对象移动到第二个SurvivorSpace(即Survivorto),同时第一个SurvivorSpace的数据也会移动到第二个SurvivorSpace。如果填充到Survivorto的对象被Survivorfrom或EdenSpace中的对象引用,那么系统会认为它们生命周期比较长,就会把它们移动到老年代。经过年轻代和老年代来来回回的新建、回收(MinorGC、MajorGC),不断的释放内存给程序用,如果不能够释放足够的内存空间,就会执行FullGC,把所有在堆中运行的线程清除。

那么年轻代和老年代又是使用什么算法进行垃圾回收的呢 ?在年轻代中使用的是复制-清除算法,所谓复制清除算法指的是在执行MinorGC时,先将应用程序挂起,将Eden和Survivorfrom中存活的对象复制到Survivorto当中,然后清除掉Eden和Survivorfrom中的对象,MinorGC是很频繁的。在老年代使用的是标记-清除算法,在执行MajorGC时,把对象标记出来,然后清除掉,MajorGC是比较低频的。值得注意的是在GC时会产生很多内存碎片,如果有较大的对象要从年轻代进入老年代,但并不能找到合适的存储空间时,也会触发GC。

垃圾回收算法是在垃圾回收器中实现和运行的,在JDK厂商(包含OracleJDK、HPJDK、IBMJDK)中也提供了不同的垃圾收集器。对于年轻代实现分别是Serial收集器、ParallelScavenge收集器、ParNew收集器,在老年代中是SerialOld(Mark Sweep Compact)收集器、ParallelOld(PSMarkSweep)收集器、CMS(ConcurrentMarkSweep)收集器。

年轻代垃圾回收器中,Serial收集器是一种单线程收集器,使用单个GC线程进行垃圾回收,在垃圾回收时,将整个应用程序挂起(stopthe world),然后复制-清除;ParallelScavenge是多线程收集器,使用多个GC线程进行垃圾回收;ParNew也是一种多线程回收器,使用多个GC线程回收,可以和CMS一起使用。老年代垃圾回收器中,SerialOld是一种单线程回收器,使用单个