前言:垃圾回收机制,大家都知道JAVA的垃圾回收都是JVM自动回收的,不需要程序员去管理。但是我们还是得知道原理才能在适当时机进行JVM调优

  原理:当我们new 一个对象时JVM堆区就会分配一块内存(地址,大小)给这个对象,当这个对象“不可达”的时候(即程序无法访问的时候),GC就需要回收这块空间。

  Java语言规范没有明确地说明JVM使用哪种垃圾回收算法,但是任何一种垃圾回收算法一般要做2件基本的事情:(1)发现无用信息对象;(2)回收被无用对象占用的内存空间,使该空间可被程序再次         使用,

  算法包括:

  1. 引用计数(Reference Counting):给每个对象添加一引用计数器,每当有一个地方引用它的时候,计数器+1;引用失效的时候,计数器-1

  2.可达性分析算法(Rearchability Analysis):通过一系列的“GC roots”的对象作为起点,从这些节点向下搜索,搜索所超过的路径称为引用链,当一个对象到GC roots没有任何引用链相连的时候则此对         象是不可用的,不可用的对象则是JVM判定为可回收的对象。目前Java中可以作为GC ROOT的对象有:

                    1、虚拟机栈中引用的对象(本地变量表)

                    2、方法区中静态属性引用的对象

                    3、方法区中常亮引用的对象

                    4、本地方法栈中引用的对象(Native对象)

  

  3. 标记-清除(Mark-Sweep):从引用的根节点开始标记所有引用的对象,遍历整个堆内存,把未标记的对象清楚(老年代)

   4. 复制(Copying):把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另外一个区域中(年轻代)

   5. 标记-整理(Mark-Compact :第一阶段从根节点开始标记所有被引用对象,第二阶段遍历整个堆,把清除未标记对象并且把存活对象 “压缩”到堆的其中一块,按顺序排放(老年代)

  6. 分代(Generational Collecting

  首先我们得先清除JVM堆内存的结构(如下图),可以看到一共有3个区域:年轻代(Young Generation)、老年代(Old Generation)、永久代(Permanent Generation,也就是方法区)

  

 年轻代(Young Generation)

  包括一个Eden区和2个Survivor 区(From 和 to  ),绝大多数的对象刚创建时都被分配在Eden区(Eden区是连续的内存空间,因此在其上分配内存极快),当第一次Eden区空间满了的时候进行第一            次Minor GC:回收掉“消亡”的对象,存活的对象复制到From内存 中(To内存此时是空的),Eden区域为空;下次Eden满的时候,又会触发Minor GC,回收掉消亡对象,存活的对象还是复制到From内存          中,当From内存满了的时候,GC会把From中还存活的对象复制到To内存中吗,清空From,这就确保了From和To永远至少有一个区是空的;重复以上步骤依然存活的对象会被默认放到老年代中。在年轻          代发生的GC只有Minor GC,发生的频率比较高(不一定是Eden满的时候)

老年代(Old Generation)

存放经历N次Minor GC依然存活的对象,当老年代的内存空间满的时候会触发Full GC,Full GC发生频率比较低,老年代对象存活时间比较长,存活率标记高

     永久代(Permanent Generation也就是方法区

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

总结的一些常见问题:

Q:JVM GC回收哪个区域内的垃圾?

JVM GC只回收堆区和方法区内的对象。而栈区的数据,在超出作用域后会被JVM自动释放掉,所以其不在JVM GC的管理范围内

 Q:JVM GC怎么判断对象可以被回收了?

对象没有引用

作用域发生未捕获异常

程序在作用域正常执行完毕

程序执行了System.exit()

程序发生意外终止(被杀线程等)

PS:上面那个是网上的答案,我个人觉得应该回答从GC root搜索不到,而且经过第一次标记、清理后,仍然没有复活的对象被回收更加合理

Q:GC策略都有哪些分类?

   引用计数:难解决对象之间相互引用的问题

   可达性分析算法:基本所有GC算法都引用根搜索算法这种概念

   标记-清除 :会有内存碎片

 复制:是对象的存活率非常低

标记-整理(Mark-Compact)缺点:成本大

   JVM为了优化内存的回收,使用了分代回收的方式,对于新生代内存的回收(Minor GC)主要采用复制算法。而对于老年代的回收(Major GC),大多采用标记-整理算法 

  Q:什么时候一个对象会被GC ?

 把minor GC和Full GC介绍下即可

Q:如果老年代的对象需要引用新生代的对象,会发生什么呢?

为了解决这个问题,老年代中存在一个 card table ,它是一个512byte大小的块。所有老年代的对象指向新生代对象的引用都会被记录在这个表中。当针对新生代执行GC的时候,只需要查询 card table 来决     定是否可以被回收,而不用查询整个老年代。这个 card table 由一个write barrier 来管理。write barrier给GC带来了很大的性能提升,虽然由此可能带来一些开销,但完全是值得的。

 总结:其实GC只要了解了三个问题就行 “什么时候”,“对什么东西”,‘“做了什么”

  

JAVA复习笔记之GC部分的更多相关文章

  1. java复习笔记

    本笔记(无异常处理与网络编程部分)整理自<java程序设计>-黄岚 王岩 王康平 编著 java数据     UI     I/O      java线程      数据库操作 Java数 ...

  2. 【Java】Java复习笔记-第一部分

    配置java环境变量 JAVA_HOME:配置JDK的目录 CLASSPATH:指定到哪里去找运行时需要用到的类代码(字节码) PATH:指定可执行程序的位置 LINUX系统 (在" .ba ...

  3. JAVA复习笔记分布式篇:zookeeper

        前言:终于到分布式篇,前面把JAVA的一些核心知识复习了一遍,也是一个JAVA程序员最基本要掌握的知识点,接下来分布式的知识点算是互联网行业的JAVA程序员必备的技能:     概念:ZooK ...

  4. JAVA复习笔记:内存结构和类加载

    Part1:JVM内存结构 JVM定义了若干个程序执行期间使用的数据区域.这个区域里的一些数据在JVM启动的时候创建,在JVM退出的时候销毁.而其他的数据依赖于每一个线程,在线程创建时创建,在线程退出 ...

  5. 【私人向】Java复习笔记

    此笔记学习于慕课网:Java入门第一季-第三季,想学的可以点击链接进行学习,笔记仅为私人收藏 建议学习时间:2-3天(极速版) 数据类型 基本数据类型存的是数据本身 引用类型变量(class.inte ...

  6. Java复习笔记--java中this 关键字

    Java中this关键字,this可以调用类的成员变量和成员方法,this还可以调用类中的构造方法.使用这种方式值得注意的是, 只可以在无参构造方法中的第一句使用this关键字调用有参构造方法. pu ...

  7. 【Java】Java复习笔记-第四部分

    反射 反射: 在运行时动态分析或使用一个类进行工作. java.lang.Class类:描述类信息的类. 类对象:描述一个类信息的对象,当虚拟机加载类的时候,就会创建这个类的类对象并加载该对象,Cla ...

  8. 【Java】Java复习笔记-三大排序算法,堆栈队列,生成无重复的随机数列

    冒泡排序 package com.lcw.bubble; public class BubbleSort { /** * 冒泡排序 * @param args * @author 成鹏致远 */ pu ...

  9. 【Java】Java复习笔记-第三部分

    修饰符abstract 抽象的,定义框架不去实现,可以修饰类和方法 abstract修饰类: 会使这个类成为一个抽象类,这个类将不能生成对象实例,但可以做为对象变量声明的类型,也就是编译时类型 抽象类 ...

随机推荐

  1. bzoj 4521: [Cqoi2016]手机号码

    感觉get到了一种数位dp的新姿势,加一位表示当前要填的数有没有限制(感觉以前的写法都太蠢了). 这么写有两个地方要注意: 1.每dp到一位时需要f[i][初始状态]++,相当于这位前都是前导零(这道 ...

  2. 发送邮件 tp5.1 5.0都可以,实测有效

    https://www.cnblogs.com/zhensg123/p/8954175.html 博客文章少了个Expection.php 文件; common.php <?php // 应用公 ...

  3. linux基础命令之sed

    什么是sed? sed是一个流编辑器,英文全名为stream editor,流的意思就是能处理文件或者通过管    道传输来的数据.主要针对行,也就是行编辑.默认是不编辑文件的,处理时,把当前    ...

  4. 【转载】14个你可能不知道的 JavaScript 调试技巧

    了解你的工具可以极大的帮助你完成任务.尽管 JavaScript 的调试非常麻烦,但在掌握了技巧 (tricks) 的情况下,你依然可以用尽量少的的时间解决这些错误 (errors) 和问题 (bug ...

  5. Python设计模式(六大)

    1.外观模式(Facade) 一层一层向上封装,灵活性会降低,功能完成度高,和python的模块比较像,但对于封装好了的类,将会变得很简单,简洁. 2.六大设计原则 单一职责原则 (Single Re ...

  6. 前端案例分享(一):CSS+JS实现流星雨动画

    目录 引言 1.效果图 2.源码 3.案例解析 4.小问题 5.结语 引言        平常会做一些有意思的小案例练手,通常都会发到codepen上,但是codepen不能写分析.        所 ...

  7. bzoj千题计划124:bzoj1036: [ZJOI2008]树的统计Count

    http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分板子题 #include<cstdio> #include<iost ...

  8. study later

    二分图匹配.左偏树.替罪羊树 四边形不等式优化 http://txhwind.blog.163.com/blog/static/203524179201242021458422/ http://www ...

  9. Javascript 常用的工具函数,更新中...

    1.时间戳转为格式化时间 /** * 时间戳转为格式化时间 * @Author chenjun * @DateTime 2017-11-10 * @param {[date]} timestamp [ ...

  10. soj1763.传球游戏

    题目不算很难,dp的转移方程也很容易列出: 设dp[i][j] 代表第i次传球之后球回到j手中的传球数.易得: dp[i][j] = dp[i-1][j-1] + dp[i-1][j-1] 再处理一下 ...