堆里面存放着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. python绘图问题

    论文绘图整理 # coding: utf-8 #来源:https://blog.csdn.net/A_Z666666/article/details/81165123 import matplotli ...

  2. 【Codeforces Round #451 (Div. 2) C】Phone Numbers

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 用map<string,vector > dic;模拟就好. 后缀.翻转一下就变成前缀了. 两重循环剔除这种情况不输出就 ...

  3. 数据库SQL Server2012笔记(七)——java 程序操作sql server

    1.crud(增删改查)介绍:create/retrieve/update/delete 2.JDBC介绍 1)JDBC(java database connectivity,java数据库连接) 2 ...

  4. 淺談Unity 5.4新功能:Light Probe Proxy Volume

    作者:CHRISTOPHER POPE 原文連結 Unity 5.4進入到Beta的階段.当中一個特別的功能是光照探頭代理Light Probe Proxy Volume(LPPV).本篇會向大家介紹 ...

  5. textview-显示行数限制

    在代码中直接添加 android:maxLines="2" android:ellipsize="end" 跟ellipsize搭配使用,超过两行的时候,第二行 ...

  6. Android学习笔记之Bitmap位图的旋转

    位图的旋转也可以借助Matrix或者Canvas来实现. 通过postRotate方法设置旋转角度,然后用createBitmap方法创建一个经过旋转处理的Bitmap对象,最后用drawBitmap ...

  7. HTML基础第三讲---字体

    转自:https://i.cnblogs.com/posts?categoryid=1121494 同样我们在这里继续讲一下它的body,因为它能直观的让大家观察到你所学到的成果. 这一讲,我们来学习 ...

  8. localStorage存储数据位置

    chrome浏览器:C:\Users\Username\AppData\Local\Google\Chrome\User Data\Default\Local Storage 中,虽然后缀名是.loc ...

  9. 全然用linux工作,放弃windows

    按: 虽然我们已经不习惯看长篇大论, 但我还是要说, 这是一篇值得你从头读到尾的长篇文章. 2005年9月22日,清华在读博士生王垠在水木社区BLOG上发表了<清华梦的粉碎--写给清华大学的退学 ...

  10. js的AJAX请求有关知识总结

    什么是AJAX?AJAX作用是什么? async javascript and xml(异步的javascript和xml) 作用:实现局部刷新 async:我们真实项目中一般使用AJAX从服务器端获 ...