大战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的时候都或多或少接触过一点,然后几乎有下面几种情况 ...
随机推荐
- 1. Linux系统介绍
1. 什么是操作系统? 定义:操作系统是计算机系统中必不可少的基础系统软件,它的作用是负责管理和控制计算机系统中的硬件和软件资源,合理地组织计算机系统的工作流程,以便有效地利用资源为使用者提供一个功能 ...
- centos7搭建zabbix3.0监控系统
关闭防火墙和selinux systemctl stop firewalld.service (停止防火墙) systemctl disable firewalld.se ...
- RF经验~~
在用RF进行web自动化脚本编写时,经常会用到对日期控件进行操作.目前认为比较好用的方法是:直接对日期控件进行赋值. Assign Id To Element //*[@id="update ...
- cnn神经网络入门
1.神经网络最基本的原理也是函数拟合,所以lose function就显得非常重要了,我们训练的目的之一就是减小损失函数,常用的损失函数参考:https://www.cnblogs.com/hypnu ...
- RTN 实操
创建房间 test-rtn 10001 e2uii6r7r 8LfwOcreM76OiV1V1y8jXrMG_BNa-cmktpWUznRa:kdYdsEpcYLc5ceWEHPaK0ZDI7Qc=: ...
- 轮播效果/cursor
cursor属性:改变鼠标中的属性 例如: cursor:pointer(鼠标移动上去变小手) <!doctype html> <html> <head> < ...
- 关于Tensorflow安装opencv和pygame
1.安装opencv https://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv C:\ProgramData\Anaconda3\Lib\site-pack ...
- React Native 断点调试 跨域资源加载出错问题的原因分析
写在前面 ————如果从头开始看还没解决,试试文章最后的绝招 闲来无事,折腾了一下React Native,相比之前,开发体验好了不少.但在真机断点调试那里遇到了跨域资源加载出错的问题,一番探索总算解 ...
- [Swift]LeetCode150. 逆波兰表达式求值 | Evaluate Reverse Polish Notation
Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, ...
- [Swift]LeetCode812. 最大三角形面积 | Largest Triangle Area
You have a list of points in the plane. Return the area of the largest triangle that can be formed b ...