前言:垃圾回收机制,大家都知道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. oracle进阶之分析函数

    本博客是自己在学习和工作途中的积累与总结,纯属经验之谈,仅供自己参考,也欢迎大家转载,转载时请注明出处. http://www.cnblogs.com/king-xg/p/6797119.html 分 ...

  2. css overflow用法

    1. overflow-y: auto 侧边栏滚动效果:overflow-y:auto 2. overflow-y: scroll 如果使用overflow:scroll的话,滚动条就一直都在,页面不 ...

  3. windows查找端口占用/ 终结端口占用 ------------windows小技巧

    前沿 我是一名小程序员,经常通过一些类似tomcat,jettry 等服务器工具 调试项目.有时候莫名其妙的就会出现 程序关闭不正常的情况!去查端口又死活找不到!最后只能重启电脑 后面,在网上查了一些 ...

  4. 通过网络仓库建立本地的yum仓库

    [root@kazihuo ~]# yum -y install createrepo yum-utils [root@kazihuo ~]# yum -y install https://mirro ...

  5. Linux文件系统_每一个的意义

    2017年1月10日, 星期二 Linux文件系统_每一个的意义 rootfs: 根文件系统 FHS:Linux /boot: 系统启动相关的文件,如内核.initrd,以及grub(bootload ...

  6. c# 判断一个数是不是质数或者求一个数的公约数的算法

    一个数是不是质数,就是判断一个数除了1和它本身还有没有其他的约数,如果有则是合数,否则是质数.其实本质都是求公约数. 求公约数是什么思路呢,就是找比它小的数不断尝试,能被整除则是其约数,否则继续尝试, ...

  7. Java并发编程原理与实战十:单例问题与线程安全性深入解析

    单例模式我想这个设计模式大家都很熟悉,如果不熟悉的可以看我写的设计模式系列然后再来看本文.单例模式通常可以分为:饿汉式和懒汉式,那么分别和线程安全是否有关呢? 一.饿汉式 先看代码: package ...

  8. CSS3实战之多列

    CSS2中如果要设计多列布局,常用的方法有浮动和定位,但是浮动容易错位,定位无法满足模块的自适应能力,以及模块之间的文档流联动的需要.为了解决多列布局的难题,CSS3新增了多列自动布局功能. 利用多列 ...

  9. iOS二维码扫描的实现(Swift)

    随着二维码的普遍使用,二维码扫描也成为了很多app的一个基本功能,本篇主要来介绍一下如何实现一个简单的二维码扫描功能.本文使用了XCode自带的AVFoundation 库,利用Swfit语言实现. ...

  10. 学号20155308 2016-2017-2 《Java程序设计》第5周学习总结

    学号20155308 2016-2017-2 <Java程序设计>第5周学习总结 教材学习内容总结 8.1 语法与继承架构 使用try...catch 注意多个catch一定把父类放后面 ...