大战Java虚拟机【2】—— GC策略
前言
前面我们已经知道了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策略的更多相关文章
- java虚拟机(十三)--GC调优思路
GC调优对我们开发人员来说,如果你想要技术方面一直发展下去,这部分内容的了解是必不可少的,jvm对于工作.面试来说都很重要,GC调优的问题 更是重中之重,因为是对你jvm学习内容的实践,知识只有应用实 ...
- java虚拟机之GC(转)
垃圾回收主要内容: 1. 那些内存需要回收? 2. 什么时候回收? 3. 如何回收? 垃圾回收主要针对运行时数据区那些区域? 运行时数据区的线程私有区域有:虚拟机栈,本地方法栈,程序计数器等: 栈中的 ...
- java虚拟机(十一)--GC日志分析
GC相关:java虚拟机(六)--垃圾收集器和内存分配策略 java虚拟机(五)--垃圾回收机制GC 打印日志相关参数: -XX:+PrintGCDetails -XX:PrintGCTimestam ...
- 深入理解java虚拟机,GC参考手册
深入理解java虚拟机 一.<深入理解Java虚拟机> 1.第2章 Java内存区域与内存溢出异常 2.第3章 垃圾收集器与内存分配策略 3.第4章 虚拟机性能监控与故障处理工具 4.第5 ...
- 小白请教几个关于Java虚拟机内存分配策略的问题
最近在看周志明所著的<深入理解Java虚拟机>,有几个问题不太明白,希望对虚拟机有研究的哥们儿帮我解答一下.先说一下我进行试验的环境: 操作系统:Mac OS X 10.11.6 EI C ...
- Java虚拟机之GC
⑴背景 Java堆和方法区实现类所需内存是不一样的,每个方法的多分支需要的内存也可能不一样,我们只有在运行期间才能制动创建哪些对象.这部分内存分配与回收都是动态的,而垃圾回收器所关注的就是这些这部分内 ...
- 大战Java虚拟机【1】—— 内存
前言 要了解Java虚拟机首先要知道的基础就是内存.虚拟机存在的意义就是对内存进行管理,因为不用人为的去管理每个对象的内存,所以才让java使用起来那么方便,不用像c.c++那样去free. 运行时数 ...
- Java 虚拟机枚举 GC Roots 解析
JVM 堆内存模型镇楼. 读<深入理解 Java 虚拟机>第三章GC算法,关于 GC Roots 枚举的段落没说透彻,理解上遇到困惑.因此对这点进行扩展并记录,发现国内各种博客写来写去都是 ...
- 大战Java虚拟机【0】——目录
发现一直在上层应用更新博客的我,突然发现也是时候同时更新一波基础知识了.然后就发现了一个点我还没有更新过,那就是Java虚拟机. 很多人在学习Java的时候都或多或少接触过一点,然后几乎有下面几种情况 ...
随机推荐
- RF无线射频电路设计干货分享
1.概述:射频(RF)PCB设计,在目前公开出版的理论上具有很多不确定性,常被形容为一种“黑色艺术”.通常情况下,对于微波以下频段的电路(包括低频和低频数字电路),在全面掌握各类设计原则前提下的仔细规 ...
- BZOJ.4842.[NEERC2016]Delight for a Cat(费用流)
BZOJ 参考这儿. 首先如果一个活动的时间满足条件,那么另一个活动也一定满足.还有就是这题就是费用流没有为什么.不妨假设最初所有时间都用来睡觉,那么我们要对每个\(k\)大小区间选出\([t2,k- ...
- lua_table 学习
lua table (表) Table 的常用操作 local fruits = {“aaa”,”bbb”,”ccc”,”ddd”,”eee”,”fff”,”ggg”} table.co ...
- POJ3630
Tire树裸题,一开始写动态的字典树,然后TLE,每次new一个新节点耗费时间较多.后来改成数组模拟的. //#include <bits/stdc++.h> #include <c ...
- Egret获取和显示时间,年,月,日,时分秒
let now = new Date(); this.nowYear = now.getFullYear(); this.nowMonth = now.getMonth() + 1; let noww ...
- git 配置 .ssh key
1.安装git软件: 2.打开本地git bash,使用如下命令生成ssh公钥和私钥对: ssh-keygen -t rsa -C 'xxx@xxx.com' 然后一路回车(-C 参数是你的邮箱 ...
- node 重新安装依赖模块
rm -rf node_modules rm package-lock.json npm cache clear --force npm install
- web 10
一.Iterations : 1.do...while : 创建执行指定语句的循环,直到测试条件评估为false.在执行语句后评估条件,导致指定语句至少执行一次. 例子:在以下示例中,do...而循环 ...
- 四、蛋炒饭(Egg fried rice)
蛋炒饭,是一种常见菜肴.最早的记载见于1972年湖南长沙马王堆汉墓出土的竹简上有关"卵火高"的资料.经专家考证,"卵熇"是一种用黏米饭加鸡蛋制成的食品.有人推断 ...
- Portainer介绍
Portainer是Docker的图形化管理工具,提供状态显示面板.应用模板快速部署.容器镜像网络数据卷的基本操作(包括上传下载镜像,创建容器等操作).事件日志显示.容器控制台操作.Swarm集群和服 ...