深入理解JVM:垃圾收集器与内存分配策略
堆里面存放着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:垃圾收集器与内存分配策略的更多相关文章
- 深入理解JVM - 垃圾收集器与内存分配策略 - 第三章
引用计数算法——判断对象是否存活的算法 很多教科书判断对象是否存活的算法是这样的:给对象添加一个引用计数器,每当一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象 ...
- jvm垃圾收集器与内存分配策略
一.垃圾回收 1.对象是否已经变为垃圾 1.1.引用计数法:给对象添加一个引用计数器,每当有地方引用它时,计数器就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象就是不可能再被使用的. 这 ...
- 深入理解JVM-3垃圾收集器与内存分配策略
在上面一篇文章中,介绍了java内存运行时区域,其中程序计数器.虚拟机栈.本地方法栈3个区域随线程生灭:栈中的栈帧随着方法的进入和退出而有条不紊的执行着进栈出栈的操作,每一个栈帧中分配着多少内存基本上 ...
- JVM垃圾收集器与内存分配策略(一)
在前面的Java自动内存管理机制(上)和Java自动内存管理机制(下)中介绍了关于JVM的一些基础知识,包括运行时数据区域划分和一些简单的参数配置,而其中也谈到了GC,但是没有深入了解,所以这里开始简 ...
- jvm系列(二)jvm垃圾收集器与内存分配策略
众所周知,在java语言中,内存分配和回收是由jvm自动管理的.因此内存的分配和回收也是jvm三大功能之一.垃圾收集器(GC)需要完成三件事情: 哪些内存需要回收? 什么时候进行回收? 如何回收? 本 ...
- JVM·垃圾收集器与内存分配策略之垃圾收集器!
1.Serial(串行)收集器(新生代都采用复制算法) 这是个单线程的收集器:即 当他工作的时候,会停掉虚拟机所有的线程!(Stop The World)
- JVM·垃圾收集器与内存分配策略之垃圾回收算法!
1.垃圾回收算法 1.1.标记-清除算法(Mark-Sweep): 过程分为“标记”和“清除”两个过程.先将所有需要回收的目标统一标记,然后再统一清除. ...
- JVM·垃圾收集器与内存分配策略之对象是否可被回收!
1.判断对象已经死去/不再被引用. 1.1.引用计数算法:给对象添加引用计数器,有个地方引用就+1,引用失效就-1.任何时刻,引用为0,即判断对象死亡. 1.1.1.优点:实现 ...
- java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收集(Garbage Collection,下文简称GC),大部分人都把这项 ...
- jvm系列 (二) ---垃圾收集器与内存分配策略
垃圾收集器与内存分配策略 前言:本文基于<深入java虚拟机>再加上个人的理解以及其他相关资料,对内容进行整理浓缩总结.本文中的图来自网络,感谢图的作者.如果有不正确的地方,欢迎指出. 目 ...
随机推荐
- JavaScript 实现表格单列按字母排序
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title> ...
- windows下使用cpanm进行模块安装
windows下使用cpanm进行模块安装 要放假了,突然想整理一下手头上的软件,突然发现perl的安装模块这个功能不能用. 弄了一下,使得windows 下 perl 的 cpanm能用,避免成天为 ...
- string-format样式使用
首先我们看如下代码 protected String calcu1() { StringBuffer resultB = new StringBuffer(); String str = null; ...
- 洛谷 P2807 三角形计数
P2807 三角形计数 题目背景 三角形计数(triangle) 递推 题目描述 把大三角形的每条边n等分,将对应的等分点连接起来(连接线分别平行于三条边),这样一共会有多少三角形呢?编程来解决这个问 ...
- 图灵机器人API,适用于微信、微博、QQ群、智能硬件等
该API有智能聊天.查天气.查快递.查菜谱.查车票.查航班.查出行.查周边等近500个功能,能够用在微信公众平台.QQ群.手机语音助手.智能硬件等领域\ [1].[代码] [PHP]代码 跳至 [1] ...
- [ACM] POJ 1046 Color Me Less
Color Me Less Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 30146 Accepted: 14634 D ...
- 怎么做好看的html5游戏界面
怎么做好看的html5游戏界面 一.总结 一句话总结:html5应该是完全可以做特别好看的游戏界面的.最下面那个背景图完全是一张图片动的雪和小动物可以是gif,或者是canvas,右边的那各个选择框就 ...
- session的生命周期是怎样的
session的生命周期是怎样的 一.总结 一句话总结:Tomcat中Session的默认失效时间为20分钟.如果我们敲代码的时候把它设置成1个月,那么这一个月的数据会代替默认20分钟的数据,使ses ...
- Vue里父子组间的通讯
父组件代码 <template> <div> <child @child-say="listenToBoy" :mes=count></c ...
- Centos 6 vnc 部署
一.安装gnome桌面环境 yum groupinstall -y 'X Window System' yum groupinstall -y "Desktop" 二.部署vnc ...