4.JVM垃圾回收机制
4.1.新生代的GC
4.1.1.串行GC(SerialGC)
4.1.2.并行回收GC(Parallel Scavenge)
4.1.3.并行GC(ParNew)
4.2.GC(Minor GC、FullGC)
4.2.1.Minor GC
4.2.2.FullGC
4.3.GC日志

4.JVM垃圾回收机制

JVM分别对新生代和老年代采用不同的垃圾回收机制。

4.1.新生代的GC

新生代通常存活时间较短,因此基于复制算法来进行回收,所谓复制算法就是扫描出存活的对象,并复制到一块新的完全未使用的空间中,对应于新生代,就是在Eden和其中一个Survivor,复制到另一个之间Survivor空间中,然后清理掉原来就是在Eden和其中一个Survivor中的对象。新生代采用空闲指针的方式来控制GC触发,指针保持最后一个分配的对象在新生代区间的位置,当有新的对象要分配内存时,用于检查空间是否足够,不够就触发GC。当连续分配对象时,对象会逐渐从eden到 survivor,最后到老年代。

用java visualVM来查看,能明显观察到新生代满了后,会把对象转移到旧生代,然后清空继续装在,当旧生代也满了后,就会报OutOfMemory的异常。

在执行机制上JVM提供了串行GC(SerialGC)、并行回收GC(ParallelScavenge)和并行GC(ParNew)。

4.1.1.串行GC(SerialGC)

在整个扫描和复制过程采用单线程的方式来进行,适用于单CPU、新生代空间较小及对暂停时间要求不是非常高的应用上,是client级别默认的GC方式,可以通过-XX:+UseSerialGC来强制指定。

4.1.2.并行回收GC(Parallel Scavenge)

在整个扫描和复制过程采用多线程的方式来进行,适用于多CPU、对暂停时间要求较短的应用上,是server级别默认采用的GC方式,可用-XX:+UseParallelGC来强制指定,用-XX:ParallelGCThreads=4来指定线程数。

4.1.3.并行GC(ParNew)

与旧生代的并发GC配合使用。

旧生代的GC:
旧生代与新生代不同,对象存活的时间比较长,比较稳定,因此采用标记(Mark)算法来进行回收,所谓标记就是扫描出存活的对象,然后再进行回收未被标记的对象,回收后对用空出的空间要么进行合并,要么标记出来便于下次进行分配,总之就是要减少内存碎片带来的效率损耗。在执行机制上JVM提供了串行 GC(SerialMSC)、并行GC(parallelMSC)和并发GC(CMS),具体算法细节还有待进一步深入研究。

4.2.GC(Minor GC、FullGC)

GC分为两种:Minor GC、FullGC(或称为Major GC)。

4.2.1.Minor GC

从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为Minor GC。
当发生Minor GC事件的时候,有一些有趣的地方需要注意到:
当 JVM 无法为一个新的对象分配空间时会触发 Minor GC,比如当 Eden 区满了。所以分配率越高,越频繁执行 Minor GC。
内存池被填满的时候,其中的内容全部会被复制,指针会从0开始跟踪空闲内存。Eden 和 Survivor 区进行了标记和复制操作,取代了经典的标记、扫描、压缩、清理操作。所以 Eden 和 Survivor 区不存在内存碎片。写指针总是停留在所使用内存池的顶部。
执行 Minor GC 操作时,不会影响到永久代。从永久代到年轻代的引用被当成 GC roots,从年轻代到永久代的引用在标记阶段被直接忽略掉。
质疑常规的认知,所有的 Minor GC都会触发”stop-the-world”,停止应用程序的线程。对于大部分应用程序,停顿导致的延迟都是可以忽略不计的。其中的真相就是,大部分 Eden区中的对象都能被认为是垃圾,永远也不会被复制到Survivor区或者老年代空间。如果正好相反,Eden 区大部分新生对象不符合 GC 条件,Minor GC 执行时暂停的时间将会长很多。

每次Minor GC会清理年轻代的内存。

Minor GC是发生在新生代中的垃圾收集动作,所采用的复制算法。

当一个对象被判定为”死亡”的时候,GC就有责任来回收掉这部分对象的内存空间。新生代是GC收集垃圾的频繁区域。

当对象在Eden (包括一个 Survivor 区域,这里假设是 from 区域)出生后,在经过一次Minor GC后,如果对象还存活,并且能够被另外一块Survivor区域所容纳(上面已经假设为 from 区域,这里应为to 区域,即to区域有足够的内存空间来存储Eden和from区域中存活的对象),则使用复制算法将这些仍然还存活的对象复制到另外一块Survivor区域(即to区域)中,然后清理所使用过的Eden以及Survivor区域(即from区域),并且将这些对象的年龄设置为1,以后对象在Survivor 区每熬过一次 Minor GC,就将对象的年龄+ 1,当对象的年龄达到某个值时 ( 默认是 15 岁,可以通过参数 -XX:MaxTenuringThreshold来设定),这些对象就会成为老年代
但这也不是一定的,对于一些较大的对象(即需要分配一块较大的连续内存空间)则是直接进入到老年代。

4.2.2.FullGC

Full GC是发生在老年代的垃圾收集动作,所采用的是标记-清除算法。

现实的生活中,老年代的人通常会比新生代的人”早死”。堆内存中的老年代(Old)不同于这个老年代里面的对象几乎个个都是在Survivor区域中熬过来的,它们是不会那么容易就”死掉”了的。
因此,Full GC发生的次数不会有Minor GC那么频繁,并且做一次Full GC要比进行一次Minor GC的时间更长

另外,标记-清除算法收集垃圾的时候会产生许多的内存碎片(即不连续的内存空间),此后需要为较大的对象分配内存空间时,若无法找到足够的连续的内存空间,就会提前触发一次GC的收集动作。

4.3.GC日志

案例

package com.toto.jvm;public class Demo {public static void main(String[] args) {Object obj = new Object();System.gc();System.out.println();obj = new Object();obj = new Object();System.gc();System.out.println();}
}

设置VM arguments:-verbose:gc -XX:+PrintGCDetails

Run之后,输出结果:

System.gc()可以触发Full GC

[GC (System.gc()) [PSYoungGen: 5201K->752K(151552K)] 5201K->760K(498688K), 0.0012719 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (System.gc()) [PSYoungGen: 752K->0K(151552K)] [ParOldGen: 8K->536K(347136K)] 760K->536K(498688K), [Metaspace: 2587K->2587K(1056768K)], 0.0088355 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] [GC (System.gc()) [PSYoungGen: 2600K->96K(151552K)] 3137K->632K(498688K), 0.0005806 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (System.gc()) [PSYoungGen: 96K->0K(151552K)] [ParOldGen: 536K->535K(347136K)] 632K->535K(498688K), [Metaspace: 2588K->2588K(1056768K)], 0.0064823 secs] [Times: user=0.03 sys=0.00, real=0.02 secs] HeapPSYoungGen      total 151552K, used 2601K [0x0000000716d00000, 0x0000000721600000, 0x00000007c0000000)eden space 130048K, 2% used [0x0000000716d00000,0x0000000716f8a578,0x000000071ec00000)from space 21504K, 0% used [0x0000000720100000,0x0000000720100000,0x0000000721600000)to   space 21504K, 0% used [0x000000071ec00000,0x000000071ec00000,0x0000000720100000)ParOldGen       total 347136K, used 535K [0x00000005c4600000, 0x00000005d9900000, 0x0000000716d00000)object space 347136K, 0% used [0x00000005c4600000,0x00000005c4685f60,0x00000005d9900000)Metaspace       used 2594K, capacity 4486K, committed 4864K, reserved 1056768Kclass space    used 288K, capacity 386K, committed 512K, reserved 1048576K

设置JVM参数为-verbose:gc -XX:+PrintGCDetails,使得控制台能够显示GC相关的日志信息,执行上面代码,下面是其中一次执行的结果。

jstate  -gc  -t  4235  1s

5.JVM参数选项

下面只列举其中的几个常用和容易掌握的配置选项

-Xms 初始堆大小。如:-Xms256m
-Xmx 最大堆大小。如:-Xmx512m
-Xmn 新生代大小。通常为Xmx的1/3 或1/4。新生代 = Eden + 2个Survivor空间。实际可用空间为 = Eden + 1 个Survivor,即90%
-Xss JDK1.5+每个线程堆栈大小为1M,一般来说如果栈不是很深的话,1M是绝对够用了的。
-XX:NewRatio 新生代与老年代的比例,如–XX:NewRatio=2,则新生代占整个堆空间的1/3,老年代占2/3
-XX:SurvivorRatio 新生代中Eden与Survivor 的比值。默认值为8。即 Eden占新生代空间的8/10,另外两个 Survivor 各占 1/10
-XX:PermSize 永久代(方法区)的初始大小
-XX:MaxPermSize 永久代(方法区)的最大值
-XX:+PrintGCDetails 打印GC信息
-XX:+HeapDumpOnOutOfMemoryError 让虚拟机在发生内存溢出时Dump出当前的内存堆转储快照,以便分析用。

-XX:Newratio: 设置Old和Yong的比例,比如值为2,则Old Generation是 Yong Generation的2倍,即Yong Generation占据内存的1/3
-XX:Newsize : 设置Yong Generation的初始值大小
-XX:Maxnewsize:设置Yong Generation的最大值大小
-XX:Surviorratio : 设置Eden和一个Suivior的比例,比如值为5,即Eden是To(S2)的比例是5,(From和To是一样大的),此时Eden占据Yong Generation的5/7

一般情况下,不允许-XX:Newratio值小于1,即Old要比Yong大。

6.元空间

元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小受本地内存限制。

4、JVM垃圾回收机制、新生代的GC、GC(Minor GC、FullGC)、GC日志、JVM参数选项、元空间(笔记)相关推荐

  1. jvm对象从新生代到老年代_JVM内存管理、JVM垃圾回收机制、新生代、老年代以及永久代...

    内存模型 JVM运行时数据区由程序计数器.堆.虚拟机栈.本地方法栈.方法区部分组成,结构图如下所示. JVM内存结构由程序计数器.堆.栈.本地方法栈.方法区等部分组成,结构图如下所示: 1)程序计数器 ...

  2. JVM内存区域(Java内存区域)、JVM垃圾回收机制(GC)初探

    一.JVM内存区域(Java内存区域) 首先区分一下JVM内存区域(Java内存区域)和Java内存模型(JMM)的概念.Java线程之间的通信采用的是共享内存模型,这里提到的共享内存模型指的就是Ja ...

  3. 【JVM】JVM垃圾回收机制GC

    文章目录 JVM垃圾回收机制 一.堆内存区域划分 1.1内存分配策略 1.2永久代(Permanent Generation) 1.3元空间(MetaSpace) 二.标记算法 2.1引用计数算法 2 ...

  4. jvm垃圾回收机制_JVM 垃圾回收机制之堆的分代回收

    JVM垃圾回收机制之堆的分代回收 前言 前文我们了解了Java的GC机制,对于堆中的对象,JVM采用引用计数和可达性分析两种算法来标记对象是否可以清除,本文中我们还会了解到JVM将对分成了不同的区域, ...

  5. JVM垃圾回收机制及算法

    JVM垃圾回收机制 在Java中,程序员是不需要像C++那样显示的去释放一个对象的内存的,而是由虚拟机自行执行.在JVM中,有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空 ...

  6. 深入理解JVM—垃圾回收机制

    一.前言 明确垃圾收集器关注的部分:堆和方法区.着重学习如何确定哪些垃圾需要回收.垃圾回收算法以及GC触发条件. 二.如何确定哪些垃圾需要回收 1.引用计数算法 在对象中添加一个引用计数器,每当有一个 ...

  7. JVM垃圾回收机制(超级无敌认真好用,万字收藏篇!!!!)

    文章目录 JVM垃圾回收机制 1 判断对象是否存活的算法 1.1 引用计数器算法 1.2 可达性分析算法 2 对象的四种引用方式 2.1 强引用 2.2 软引用 2.3 弱引用 2.4 虚引用 3 垃 ...

  8. 2020最全JVM垃圾回收机制面试题整理,阿里面试官最爱问的都在这里了(附答案)

    前言 为什么需要垃圾回收 首先我们来聊聊为什么会需要垃圾回收,假设我们不进行垃圾回收会造成什么后果,我们举一个简单的例子 我们住在一个房子里面,我们每天都在里面生活,然后垃圾都丢在房子里面,又不打扫, ...

  9. JVM架构、JVM垃圾回收机制、垃圾回收算法、垃圾回收器、JMM(内存模型)

    0 JVM和Java的关系 JDK = JRE + Java开发工具(java,javac,javadoc,javap-) JRE = JVM + Java核心类库 即: JDK = JVM + Ja ...

最新文章

  1. 飞天AI平台到底哪里与众不同?听听它的架构者怎么说
  2. File errorchecker.pyx, line 17, in OpenGL_accelerate.errorchecker._ErrorChecker.__init__ (src\erro
  3. View工作原理(一)事件传递原理详解
  4. Leetcode 12. 整数转罗马数字 (每日一题 20210827)
  5. PTAV:实时高精度目标追踪框架 | ICCV 2017论文解读
  6. 如何操控输入框中的placeholder属性
  7. [学习笔记]c#Primer中文版-类设计、static成员、const和readonly数据成员
  8. 原生态mysql_mysql基础原生sql教程
  9. 数字图像处理实验六--图像复原
  10. 工控机上位机软件的开发历程(一)
  11. 阿里二面:设计一个电商平台积分兑换系统!
  12. CSDN上Android与IPhone开发博客精选
  13. 感知机——鸢尾花 包含代码
  14. 解决opencv imwrite()影像全黑
  15. 怎么让热图显示基因名_教你画一个掰弯的热图(Heatmap),展示更多的基因表达量...
  16. Gn 与 Ninja学习和使用
  17. 直角坐标系与极坐标系了解与转换
  18. 天蓝色在ps中的色值_天蓝色的cosmosdb文档中的字段级加密
  19. 聆听朱清时教授讲创新
  20. 堆及堆排序(超超超超超详细讲解~~~~)-----数据结构

热门文章

  1. Python可视化中Matplotlib(4.三种设置样式方法、设置坐标刻度以及标签、设置显示出特殊字符)
  2. 爬虫笔记:Python Selenium详解
  3. VTK:隐藏线移除用法实战
  4. wxWidgets:wxGridUpdateLocker类用法
  5. wxWidgets:wxBitmapToggleButton类用法
  6. wxWidgets:wxBitmapComboBox类用法
  7. boost::proto模块实现简单的算术表达式求值器的测试程序
  8. boost::hana::is_nothing用法的测试程序
  9. boost::icl::split_interval_set用法的测试程序
  10. boost::biconnected_components用法的测试程序