堆里面存放着Java世界差点儿全部的对象实例,垃圾收集器在对堆进行回收前。第一件事情就是要确定这些对象之中哪些还存活,哪些已经死去。推断对象的生命周期是否结束有下面几种方法

引用计数法

详细操作是给对象加入一个引用计数器。每当有一个地方引用时。计数器的值就加1,;当引用失效时。计数器就减1。不论什么时刻计数器为0的对象就 是不可能再被使用的。客观的说引用计数器算法实现简单,判定效率也非常高,在大部分情况下他都是一个不错的算法。可是引用计数器有缺陷

举个简单的样例,对象A和对象B都有字段instance,赋值命令objA.instance = objB,objB.instance=objA,除此之外。这两个对象再无不论什么引用,实际上这两个对象已经不可能再被訪问了,可是他们由于互相引用这对方。导致引用数据器不为0,无法通知CG收集器收集他们。

public class ReferenceCountingGC{
public Object instance = null;
private static final int _1MB = 1024*1024;
// 这个成员属性的唯一意义就是占点内存,以便能在GC日志中看清楚是否被回收过
private byte[] bigSize = new byte[2*_1MB];
public static void testGC{
ReferenceCountingGC objA = new ReferenceCountingGC();
ReferenceCountingGC objB = new ReferenceCountingGC();
objA.instance = objB;
objB.instance = objA; obj.A = null;
obj.B = null;
}
}

通过GC日志。虚拟机并没有由于这两个对象互相引用就不回收他们。这从側面说明虚拟机不是通过引用计数器来推断对象是否存活。

可达性分析算法

这个算法的基本思路是通过一系列称为“GC Roots”的对象作为起始点,从这些节点開始向下搜索。搜索走过的路径称为引用链,当一个对象到GC Roots没有不论什么引用链相连。则证明此对象是不可用的。

Java语言中。可作为GC Roots的对象包括

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

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

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

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

引用分析

假设reference类型的数据中存储的数值代表的是还有一块内存的起始地址,就称为这块内存代表着一个引用。这样的定义太过狭隘,一个对象在这样的定义下仅仅有被引用和没有被引用两种状态。对于怎样描写叙述一些“食之无味。弃之可惜”的对象就显得无能为力。我们希望能描写叙述这样一类对象,当内存空间足够时。则能够保存在内存之中。假设内存空间在进行垃圾回收后还是非常紧张,则能够抛弃这些对象。

在JDK1.2以后,Java对引用进行了扩展。将引用分为强引用、软引用、弱引用、虚引用四种,强度依次递减。

1、强引用:程序中普遍存在。比如Object obj = new Object();仅仅要强引用来,CG永远不会回收

2、软引用:描写叙述一些还实用,可是并不是必要的对象。

对于软引用的对象。在系统将要发生内存溢出之前,会把这些对象列进回收范围之中进行二次回收,假设回收了还没有足够的内存将报出内存溢出,JDK1.2之后提供了SoftReference类来实现软引用。

3、弱引用:也是描写叙述非必须对象,被弱引用的对象仅仅能生存到下一次垃圾收集之前。当垃圾收集器工作时,不管内存是否够用都会被回收,JDK1.2之后提供了WeakReference类来实现弱引用。

4、虚引用:幽灵引用或者幻影引用,最弱。一个对象是否有虚无引用的存在。全然不会对其生存时间构成影响,也无法通过虚无引用来取得一个对象实例。

生存还是死亡

即使在可达性分析算法中不可达对象,也并不是是“非死不可”的,这时候他们临时出“缓刑”之中,要真正宣告一个对象死亡。至少要经历两次标记过程:假设对象在进行可达性分析后发现没有与GC Roots相连接的引用链,那他会被第一次标记而且进行一次筛查,筛查的条件是此对象是有有必要运行finalize方法。

当对象没有覆盖finalize方法,或者finalize方法已经被虚拟机调用过,虚拟机将这两种情况视为没有必要运行。

类的Finalize方法,能够告诉垃圾回收器应该运行的操作,该方法从Object类继承而来。在从堆中永久删除对象之前。垃圾回收器调用该对象的Finalize方法。注意,无法确切地保证垃圾回收器何时调用该方法,也无法保证调用不同对象的方法的顺序。即使一个对象包括还有一个对象的引用。或者在释放一个对象非常久曾经就释放了还有一个对象,也可能会以随意的顺序调用这两个对象的Finalize方法。假设必须保证採用特定的顺序,则必须提供自己的特有清理方法。

回收方法区

方法区即为Hotspot虚拟机中的永久代,永久代的垃圾收集主要回收两部分内容:废弃常量和没用的类。以常量字符串”abc”为例,已经进入常量池,可是当前系统没有不论什么一个String对象叫做abc,换句话说就是没有不论什么String对象引用常量池中的abc,假设此时发生内存回收,这个abc常量就会被系统清理出常量池。常量池中的其它类、接口、方法、字段的符号引用也与此相似。

判定一个常量是否是废弃常量比較简单,而判定一个类是否是没用的类的条件 要苛刻的多,没用的类要满足下面条件:

1、该类全部的实例都已经被回收,Java堆中不存在该类的不论什么实例。

2、载入该类的ClassLoader已经被回收

3、该类的Java.lang.class对象没有在不论什么地方被引用。无法在不论什么地方通过反射訪问该类。

深入理解JVM:垃圾收集器与内存分配策略的更多相关文章

  1. 深入理解JVM - 垃圾收集器与内存分配策略 - 第三章

    引用计数算法——判断对象是否存活的算法 很多教科书判断对象是否存活的算法是这样的:给对象添加一个引用计数器,每当一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象 ...

  2. jvm垃圾收集器与内存分配策略

    一.垃圾回收 1.对象是否已经变为垃圾 1.1.引用计数法:给对象添加一个引用计数器,每当有地方引用它时,计数器就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象就是不可能再被使用的. 这 ...

  3. 深入理解JVM-3垃圾收集器与内存分配策略

    在上面一篇文章中,介绍了java内存运行时区域,其中程序计数器.虚拟机栈.本地方法栈3个区域随线程生灭:栈中的栈帧随着方法的进入和退出而有条不紊的执行着进栈出栈的操作,每一个栈帧中分配着多少内存基本上 ...

  4. JVM垃圾收集器与内存分配策略(一)

    在前面的Java自动内存管理机制(上)和Java自动内存管理机制(下)中介绍了关于JVM的一些基础知识,包括运行时数据区域划分和一些简单的参数配置,而其中也谈到了GC,但是没有深入了解,所以这里开始简 ...

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

    众所周知,在java语言中,内存分配和回收是由jvm自动管理的.因此内存的分配和回收也是jvm三大功能之一.垃圾收集器(GC)需要完成三件事情: 哪些内存需要回收? 什么时候进行回收? 如何回收? 本 ...

  6. JVM·垃圾收集器与内存分配策略之垃圾收集器!

    1.Serial(串行)收集器(新生代都采用复制算法)     这是个单线程的收集器:即 当他工作的时候,会停掉虚拟机所有的线程!(Stop The World)

  7. JVM·垃圾收集器与内存分配策略之垃圾回收算法!

    1.垃圾回收算法    1.1.标记-清除算法(Mark-Sweep):             过程分为“标记”和“清除”两个过程.先将所有需要回收的目标统一标记,然后再统一清除.          ...

  8. JVM·垃圾收集器与内存分配策略之对象是否可被回收!

    1.判断对象已经死去/不再被引用.     1.1.引用计数算法:给对象添加引用计数器,有个地方引用就+1,引用失效就-1.任何时刻,引用为0,即判断对象死亡.         1.1.1.优点:实现 ...

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

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

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

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

随机推荐

  1. arcgis webapp builder 安装试用

    ArcGIS WebApp Builder 是针对开发者的,用于高速构建基于HTML5/Javascript 技术的美观的 Web应用的一个工具. 用过Flex版本号的AppBuilder应该非常清楚 ...

  2. Codeforces 559A Gerald&#39;s Hexagon 数三角形

    题意:按顺序给出一个各内角均为120°的六边形的六条边长,求该六边形能分解成多少个边长为1的单位三角形. 把单位三角形面积看做1,实际上就是求六边形面积.随便找六边形的三条互相不相邻的边,分别以这三条 ...

  3. 学习笔记(一):offset

    很多初学者对于JavaScript中的offset.scroll.client一直弄不明白,虽然网上到处都可以看一张图(图1),但这张图太多太杂,并且由于浏览器差异性,图示也不完全正确. 图一 不知道 ...

  4. 【ASP.NET开发】.NET三层架构简单解析

    对于三层架构来说,主要是使用设计模式的思想,对于项目的各个模块实现"高内聚,低耦合"的思想.这里就不做详细的介绍了,如果大家有兴趣,可以阅读软件工程和设计模式相关文章. 对于三层架 ...

  5. js进阶 14-4 $.get()方法和$.post()方法如何使用

    js进阶 14-4 $.get()方法和$.post()方法如何使用 一.总结 一句话总结:$.get(URL,callback); $.post(URL,data,callback); callba ...

  6. php课程 11-37 类和对象的关系是什么

    php课程 11-37 类和对象的关系是什么 一.总结 一句话总结:类生成对象,对象是类的实例化,一定是先有类,后有对象,一定是先有标准,再有个体. 1.oop的三大优势是什么? 重用性,灵活性.扩展 ...

  7. 学习笔记:mpvue开发小程序——入门

    接下来可能要开发一个小程序,同事推荐使用mpvue,那么我提前熟悉下. 官网地址:http://mpvue.com/ 1.快速上手 http://mpvue.com/mpvue/quickstart/ ...

  8. JS错误记录 - 微博发布

    <style> *{ margin: 0; padding: 0;} #ul1{ width: 400px; height: 400px; border: 1px solid #000; ...

  9. postman--基本使用2

    本文转自:http://blog.csdn.net/u013613428/article/details/51557804 最近需要测试产品中的REST API,无意中发现了PostMan这个chro ...

  10. Docker---(2)docker pull 下来的镜像存储在哪里

    原文:Docker---(2)docker pull 下来的镜像存储在哪里 版权声明:欢迎转载,请标明出处,如有问题,欢迎指正!谢谢!微信:w1186355422 https://blog.csdn. ...