3.1 概述
垃圾收集器要解决哪些问题?
  • 哪些内存需要回收
  • 什么时候回收
  • 如何回收
引用计数算法:当有一个地方引用,+1,引用失效,-1。     缺点:对象之间相互循环引用的问题。
可达性分析算法:
思路:通过一系列的成为“Gc Roots"的对象作为起始点,从这些节点开始向下探索,搜索所走过的路径成为引用链(Reference Chain),当一个对象到Gc Roots没有任何引用链相连,则则很难革命此对象是不可用的。
Java语言中GC Roots的对象包括下面几种:
  1.虚拟机栈(栈帧中的本地变量表)中引用的对象
  2.方法区中类静态属性引用的对象
  3.方法区中常量引用的对象
  4.本地方法栈JNI(Native方法)引用的对象
2.引用
  强引用就是在程序代码之中普遍存在的,类似Object obj = new Object() 这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象
  软引用用来描述一些还有用但并非必须的元素。对于它在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存才会抛出内存溢出异常
  弱引用用来描述非必须对象的,但是它的强度比软引用更弱一些,被引用关联的对象只能生存到下一次垃圾收集发生之前,当垃圾收集器工作时,无论当前内存是否足够都会回收掉只被弱引用关联的对象
  虚引用的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。
 
Finalize方法
  任何一个对象的finalize()方法都只会被系统自动调用一次,如果对象面临下一次回收,它的finalize()方法不会被再次执行,因此第二段代码的自救行动失败了。
fInalize()是Object的protected方法,子类可覆盖该方法以实现资源清理工作。
 
回收方法区
废弃常量和无用类,如String "abc"。
类要回收满足的条件:  1.该类所有的实例都已经被回收,Java堆中不存在任何实例。   2.加载该类的Class Loader已经被回收。  3. 该类对用的java.lang.Class对象没有在任何地方被引用,无法再任何地方通过反射访问该类的方法
 
3.3垃圾回收算法
1.标记-清除算法:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。
不足:效率问题,空间问题(产生大量碎片)。
 
2.复制算法
将可用内存按照容量划分为大小相等的两块,每次只使用其中的一块。当这块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。这样使得每次都是对整个半区进行内存回收,内存分配时也就不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存即可。
不足:将内存缩小为原来的一半。
实际上,将内存分为一块较大的Eden空间和Survivor空间,每次使用Eden和另一块Survivor。  
HotSpot虚拟机默认Eden:Survivor=8:1.  新生代中可用内存空间为整个新生代容量的90%。
 
3.标记-整理算法
标记之后,让所有存活的对象都向一段移动,然后直接清理掉端边界外的内存。
 
4.分代收集算法
把Java堆分为新生代和老年代,可以根据各个年代的特点采用适当的算法。
 
3.4HotSpot算法的实现
Gc进行时必须停顿所有的执行线程,Stop the world 
安全点  程序执行时并非在所有地方都能停顿下来执行GC,只有到达安全点才能暂停。 (存档点)  。
主动式中断:设置一个标志,各个线程执行时主动轮询这个标志,发现中断标志为真就自己中断挂起。
安全区域:
3.5垃圾收集器

1.Serial收集器:单线程收集器,采用复制算法: 在进行垃圾收集,必须暂停所有其他工作线程,直到它收集结束。简单而高效,
2.ParNew收集器: Serial收集器的多线程版本,可以和CMS收集器配合工作。  使用: -XX:+UseParNewGc强制指定。
3.Parallel Scavenge(清楚污物,打扫)是一个吞吐量优先的处理器   特点:CMS收集器的关注点时尽可能缩短垃圾手机时用户停顿的线程,而他的目标:达到一个可控制的吞吐量。   控制吞吐时间—XX:MaxGCPauseMillis    设置吞吐量大小:-XX:GCTimeRatio参数。
吞吐量:运行用户代码时间/(运行用户代码时间+垃圾手机时间)
GC停顿时间的缩短时以牺牲吞吐量和新生代空间来换取的。
4.Serial Old收集器,单线程收集器,使用标记-整理算法。
5.Parallel Old收集器 多线程、标记-整理算法。
6.CMS收集器(Concurrent Mark Sweep) 获取最短回收停顿时间为目标的收集器,
步骤: 初始标记 (单线程)——并发标记——重新标记(单线程)——并发清除

重新标记是为了修正并发标记期间因用户程序继续运行运作而导致标记产生变动的那一部分对象的标记记录。
缺点
  • CMS收集器对CPU资源非常敏感。 默认启动的回收线程数是(CPU数量+3)/4,CPU不足的情况下,对用户程序的影响就可能变得很大。
  • 无法处理浮动垃圾,可能出现失败而导致另一次Full GC的产生。   由于CMS并发清理阶段用户线程还在运行,伴随程序运行自然就还会有新的垃圾产生,这部分垃圾出现在标记过程之后,CMS无法在当次收集中处理掉他们,只好等待下一次GC时再清理掉。
          因此需要预留一部分空间提供并发收集的程序运作使用。
  • 基于标记-清除实现,产生大量内存碎片,给大对象分配带来麻烦。
7.G1收集器
    特点:
  • 并发与并行
  • 分代收集
  • 空间整合:整体上基于标记-整理算法。局部基于复制算法
  • 可预测的停顿
G1可以有计划地避免在整个Java堆中进行全区域的垃圾收集。G1跟踪各个Region里面的垃圾堆积的价值大小,在后台维护一个优先列表,每次根据允许的回收时间来优先回收价值最大的Region(Gabarage First ——G1的由来)。
 
不计算维护Remembered Set的操作,G1收集器的运作大致划分为几个步骤:
1.初始标记 
2.并发标记 
3.最终标记 
4.筛选回收

垃圾收集器参数: SurvivorRatio:新生代中Eden与survivor区域容量比值,默认8。即两者8:1.
 
3.6内存分配策略与回收策略
对象的内存分配,就是在堆上分配,对象主要分配在新生代的Eden区中,如果启动了TLAB,将按线程优先在TLAB上分配。也可能直接分配在老年代中。
  • 对象优先在Eden分配   当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC
  • 大对象直接进入老年代    :如字符串和数组
  • 长期存活的对象将进入老年代     虚拟机给每个对象定义了一个对象年龄计数器。如果对象在Eden出生并经过第一次Minor GC后仍然存活,且能被survivor容纳的话,将移动到survivor空间。对象在survivor每经历一次Minor GC,年龄就增加一岁,年龄增长到一定之后将进入老年代。
  • 动态对象年龄判断   如果在survivor空间中相同年龄的对象大小的总和>survivor空间的大小的一半,则这些对象直接进入老年代中,需要等待年龄判定进入。
  • 空间分配担保   在发生Minor GC 之前,虚拟机会检查老年代最大可 用的连续空间是否大于新生代所有对象总空间,如果这个条件成立,那么Minor GC可以确保是安全的。如果不成立,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。如果允许那么会继续检查老年代最大可用的连续空间是否大于晋级到老年代对象的平均大小,如果大于,将尝试进行一次Minor GC,尽管这次MinorGC 是有风险的:如果小于,或者HandlePromotionFailure设置不允许冒险,那这时也要改为进行一次Full GC
 
 
 
 

垃圾收集器与内存分配策略(深入理解Java虚拟机)的更多相关文章

  1. 垃圾收集器与内存分配策略——深入理解Java虚拟机 笔记二

    在本篇中,作者大量篇幅介绍了当时较为流行的垃圾回收器,但现在Java 14都发布了,垃圾收集器也是有了很大的进步和发展,因此在此就不再对垃圾收集器进行详细的研究.但其基本的算法思想还是值得我们参考学习 ...

  2. 深入理解java虚拟机----->垃圾收集器与内存分配策略(下)

    1.  前言 内存分配与回收策略 JVM堆的结构分析(新生代.老年代.永久代) 对象优先在Eden分配 大对象直接进入老年代 长期存活的对象将进入老年代 动态对象年龄判定 空间分配担保  2.  垃圾 ...

  3. 《深入理解Java虚拟机》(三)垃圾收集器与内存分配策略

    垃圾收集器与内存分配策略 详解 3.1 概述 本文参考的是周志明的 <深入理解Java虚拟机>第三章 ,为了整理思路,简单记录一下,方便后期查阅. 3.2 对象已死吗 在垃圾收集器进行回收 ...

  4. 《深入理解java虚拟机》第三章 垃圾收集器与内存分配策略

    第三章 垃圾收集器与内存分配策略 3.1 概述 哪些内存需要回收 何时回收 如何回收 程序计数器.虚拟机栈.本地方法栈3个区域随线程而生灭. java堆和方法区的内存需要回收.   3.2 对象已死吗 ...

  5. 深入理解java虚拟机_第三章(上)----->垃圾收集器与内存分配策略

    1.  前言 这一版块内容比较多,分为两篇文章来做笔记.本文讲述上半部分垃圾收集部分;下一篇文章写内存分配部分. 概述 对象已死吗? 引用技术算法 可达性分析算法 再谈引用 两次标记 回收方法区 2. ...

  6. java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)

    Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收集(Garbage Collection,下文简称GC),大部分人都把这项 ...

  7. jvm系列 (二) ---垃圾收集器与内存分配策略

    垃圾收集器与内存分配策略 前言:本文基于<深入java虚拟机>再加上个人的理解以及其他相关资料,对内容进行整理浓缩总结.本文中的图来自网络,感谢图的作者.如果有不正确的地方,欢迎指出. 目 ...

  8. 《深入java虚拟机》读书笔记之垃圾收集器与内存分配策略

    前言 该读书笔记用于记录在学习<深入理解Java虚拟机--JVM高级特性与最佳实践>一书中的一些重要知识点,对其中的部分内容进行归纳,或者是对其中不明白的地方做一些注释.主要是方便之后进行 ...

  9. Java虚拟机垃圾收集器与内存分配策略

    Java虚拟机垃圾收集器与内存分配策略 概述 那些内存须要回收,什么时候回收.怎样回收是GC须要完毕的3件事情. 程序计数器.虚拟机栈与本地方法栈这三个区域都是线程私有的,内存的分配与回收都具有确定性 ...

  10. JVM性能优化系列-(2) 垃圾收集器与内存分配策略

    2. 垃圾收集器与内存分配策略 垃圾收集(Garbage Collection, GC)是JVM实现里非常重要的一环,JVM成熟的内存动态分配与回收技术使Java(当然还有其他运行在JVM上的语言,如 ...

随机推荐

  1. 关于结构体占用空间大小总结(#pragma pack的使用)

    关于C/C++中结构体变量占用内存大小的问题,之前一直以为把这个问题搞清楚了,今天看到一道题,发现之前的想法完全是错误的.这道题是这样的: 在32位机器上,下面的代码中 class A { publi ...

  2. LeetCode22.括号生成 JavaScript

    给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合. 例如,给出 n = 3,生成结果为: [ "((()))", "(()())& ...

  3. winform 实现定位

    如何在winform中 导入地图实现定位功能    ? 从网上下个BaiDuMap.htm, 就是个js文件 在form中加入webBrowser控件,然后在窗体的加载事件中写入如下代码 webBro ...

  4. 课时56.marquee标签(理解)

    这个标签是比较特殊的,不是html5中的新增标签 在W3C官方文档中找不到这个标签,也就是说不是官方推荐的标签 但是各大浏览器对这个标签的支持也非常不错,而且效果也非常不错 1.什么是marquee标 ...

  5. 一点一点看JDK源码(五)java.util.ArrayList 后篇之sort与Comparator

    一点一点看JDK源码(五)java.util.ArrayList 后篇之sort与Comparator liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看JD ...

  6. SQL SERVER 对权限的授予GRANT、拒绝DENY、收回REVOKE

    -----对用户member授权,允许其具有对数据表person的更新和删除的操作权限:GRANT UPDATE,DELETE ON personTO member WITH GRANT OPTION ...

  7. Bash游戏(51Nod - 1046)

    20180603 有一堆石子共有N个.A B两个人轮流拿,A先拿.每次最少拿1颗,最多拿K颗,拿到最后1颗石子的人获胜.假设A B都非常聪明,拿石子的过程中不会出现失误.给出N和K,问最后谁能赢得比赛 ...

  8. thinkPHP5.0框架验证码调用及点击图片刷新简单实现方法

    这篇文章主要介绍了thinkPHP5.0框架验证码调用及点击图片刷新简单实现方法,结合简单示例形式分析了thinkPHP5框架验证码相关配置.后台验证.前台刷新等操作技巧,学习thinkphp源码的朋 ...

  9. ES6 imports用法

    import defaultExport from "module-name"; import * as name from "module-name"; // ...

  10. docker-compose入门示例:一键部署 Nginx+Tomcat+Mysql

    整体环境配置 整体环境的配置,如果一个一个 Dockerfile 去写,那么是相当麻烦的,好在 Docker 有一个名为 Docker-Compose 的工具提供,我们可以使用它一次性完成整体环境的配 ...