前言

前面我们已经知道了Java虚拟机所做的事情就是回收那些不用的垃圾,那些不用的对象。那么问题来了,我们如何知道一个对象我们不需要使用了呢?程序在使用的过程中会不断的创建对象,这些所创建的对象指不定在哪里我们就需要用到了呢?GC怎么知道我们不用了呢?回收就是简单的删除吗?这些问题将会在这里做出解释。

怎么判断一个对象将会被回收

说白了就是判断一个对象已经死亡,不会再被用到了。

首先我们需要知道java中有四种不一样的引用。

强引用:A a = new A()

软引用:还有用,但不是必须的对象,软引用就是连着这些对象,如果马上要内存溢出了就会尝试回收这些对象

弱引用:被弱引用关联的对象只能活到下一次GC之前

虚引用:最没用的一个,只有一个目的,在回收之前收到一个系统通知

引用计数(这个不是java虚拟机使用的)

看书的时候我就惊讶了,因为我确实也面试到很多人这个问题,回答告诉我的都是引用计数,即:用一个计数器,当有引用指向它,则加1,当失去一个引用,则减1,当引用为0时则回收。

我学过AS3,在flash里面确实是这样的,但是在java虚拟机里面不是,因为没有办法回收两个互相引用的对象。

比如A引用B,B引用A这样大家引用都不是0,就无法回收了,显然java中是可以回收这样对象的。

可达性算法

引入了GC Root的概念,从这个根必须能引用到这个对象。

(GC Root)->(A)->(B)

(C)

当C这样的对象到GC Root没有任何引用链项链的时候,也就是不可达的时候,算这个对象已经死亡。

java和C#都是使用这样算法。

上面说的都是堆中对象的死亡条件,或者说堆的的对象什么时候会被回收。

我们要知道的是,方法区其实也是可以垃圾收集的。比如当一个字符串常量没有地方引用到了这个量,如果现在方法区不够了那就会进行回收。

垃圾收集的算法

这里用最简单的话概括一下,有必要的详细了解

1、标记-清除

看名字就知道,就先标记一下要回收的对象,标记完成之后统一清除。

缺点:效率不高,清除之后碎片内存太多。

2、复制

将内存一分为A、B;用的时候就用A这块,回收的时候,将A中需要用的东西复制到B中,然后一次性清除A的区域。

优点:对象存活率不高的时候效率高,不会有内存碎片,都是一整块的。

缺点:代价高,原本挺大的一块内存硬生生是被切成了一半。(不是说所有的虚拟机都是对半分来实现复制的)

3、标记-整理

和标记清除类似,只是在清除的时候不一样,这里是整理,将存活的对象移到一起。

效率和标记清除是差不多的,但是不会有碎片内存

4、分代收集

因为不是每个收集的算法都是完美的,所以java虚拟机采用分代收集的思想,对于新生代因为有大批的对象会死亡,所以使用复制,但是对于老年代,对象的存活率高,所以采用标记整理或者标记清除。

分配

我们知道了对象是如何回收的,同时我们也需要知道对象是如何分配的。

1、对象优先分配在新生代Eden区,当没有位置的时候发起一次MinorGC

2、大的对象,如连续分配的数组直接进入老年代

3、长期存活的对象会进入老年代,没熬过一次MinorGC就增加一岁

4、当相同年龄的对象大小综合大于Survivor的一半就会将年龄大于等于这个年龄的对象直接进入老年代

5、老年代可以用作新生代的空间担保,新生代用的是复制算法,万一对象存活太多,那么需要额外的空间去弥补

针对每个收集器的具体行为和优势劣势将会在后面提出,这里暂时就到这里。

上面就是GC策略,我们所要知道的就是如何判断一个对象存活,对象怎么被回收,对象怎么被分配。

大战Java虚拟机【2】—— GC策略的更多相关文章

  1. java虚拟机(十三)--GC调优思路

    GC调优对我们开发人员来说,如果你想要技术方面一直发展下去,这部分内容的了解是必不可少的,jvm对于工作.面试来说都很重要,GC调优的问题 更是重中之重,因为是对你jvm学习内容的实践,知识只有应用实 ...

  2. java虚拟机之GC(转)

    垃圾回收主要内容: 1. 那些内存需要回收? 2. 什么时候回收? 3. 如何回收? 垃圾回收主要针对运行时数据区那些区域? 运行时数据区的线程私有区域有:虚拟机栈,本地方法栈,程序计数器等: 栈中的 ...

  3. java虚拟机(十一)--GC日志分析

    GC相关:java虚拟机(六)--垃圾收集器和内存分配策略 java虚拟机(五)--垃圾回收机制GC 打印日志相关参数: -XX:+PrintGCDetails -XX:PrintGCTimestam ...

  4. 深入理解java虚拟机,GC参考手册

    深入理解java虚拟机 一.<深入理解Java虚拟机> 1.第2章 Java内存区域与内存溢出异常 2.第3章 垃圾收集器与内存分配策略 3.第4章 虚拟机性能监控与故障处理工具 4.第5 ...

  5. 小白请教几个关于Java虚拟机内存分配策略的问题

    最近在看周志明所著的<深入理解Java虚拟机>,有几个问题不太明白,希望对虚拟机有研究的哥们儿帮我解答一下.先说一下我进行试验的环境: 操作系统:Mac OS X 10.11.6 EI C ...

  6. Java虚拟机之GC

    ⑴背景 Java堆和方法区实现类所需内存是不一样的,每个方法的多分支需要的内存也可能不一样,我们只有在运行期间才能制动创建哪些对象.这部分内存分配与回收都是动态的,而垃圾回收器所关注的就是这些这部分内 ...

  7. 大战Java虚拟机【1】—— 内存

    前言 要了解Java虚拟机首先要知道的基础就是内存.虚拟机存在的意义就是对内存进行管理,因为不用人为的去管理每个对象的内存,所以才让java使用起来那么方便,不用像c.c++那样去free. 运行时数 ...

  8. Java 虚拟机枚举 GC Roots 解析

    JVM 堆内存模型镇楼. 读<深入理解 Java 虚拟机>第三章GC算法,关于 GC Roots 枚举的段落没说透彻,理解上遇到困惑.因此对这点进行扩展并记录,发现国内各种博客写来写去都是 ...

  9. 大战Java虚拟机【0】——目录

    发现一直在上层应用更新博客的我,突然发现也是时候同时更新一波基础知识了.然后就发现了一个点我还没有更新过,那就是Java虚拟机. 很多人在学习Java的时候都或多或少接触过一点,然后几乎有下面几种情况 ...

随机推荐

  1. 黑洞版视频裂变程序【接口版】全新上线,全新UI,支持分享数据统计

    黑洞版视频裂变程序[接口版]全新上线,全新UI,支持分享数据统计!   后台效果   程序统一售价:1899/套(包安装,包更新) 注:本程序不属于之前视频程序的更新版,展现形式和广告位设置均不同,是 ...

  2. MyBatis3系列__05查询补充&resultMap与resultType区别

    1.查询补充 当你查询一条记录并且是简单查询时,情况相对简单,可以参考以下的例子: public Employee getEmpById(Integer id); 对应的xml文件中: <sel ...

  3. C语言可变参数

    前段时候在实现利用redis进行的一个数据库比对的功能,稍微去分析了一下redis里面的源代码,然后发现其中的发送命令接口声明如下: void *redisCommand(redisConnect * ...

  4. 用OleDb导入Excel时提示驱动错误问题解决办法

    导入格式为xls的excel文件,发生了错误 未处理System.Data.OleDb.OleDbException HResult=-2147467259 Message=外部数据库驱动程序 (1) ...

  5. Kiwi Syslog安装笔记

    Kiwi Syslog是一款比较好用日志服务器,采集设备.服务器日志简单又方便,近日试架成功,记录重点部分. 1. 网络设备配置 举例思科: R1#configure t R1(config)#log ...

  6. hashlib模块,shutil,模块 ,,xml 文件解析,configparser,模块,类,什么是类

    1 什么是hash hash是一种算法,该算法接受传入的内容,经过运算得到一串hash值 如果把hash算法比喻为一座工厂 那传给hash算法的内容就是原材料 生成的hash值就是生产出的产品 2.为 ...

  7. 错误:Java HotSpot(TM) 64-Bit Server VM warning: Insufficient space for shared memory file

    Java HotSpot(TM) 64-Bit Server VM warning: Insufficient space for shared memory file: /tmp/hsperfdat ...

  8. ES6新增对象方法的访问描述符:get(只读)、set(只写)

    Es6新增对象方法的访问描述符:get(只读).set(只写),可以直接使用,一般用于数据监听,用途类似于vue.$watch. var obj = { a:1, get bar() { return ...

  9. Objective-C 优秀文章分享

    1.  Objective-C Runtime 2.KVO + Block 3.Method Swizzling 和 AOP 实践

  10. react-native-upgrade-android

    React Native的版本升级插件(仅是android), react-native版本需要0.17.0及以上 如何安装 1.首先安装npm包 npm install react-native-u ...