老生常谈Java虚拟机垃圾回收机制 在Java虚拟机中,对象和数组的内存都是在堆中分配的,垃圾收集器主要回收的内存就是在堆内存中。如果在Java程序运行过程中,动态创建的对象或者数组没有及时得到回收,持续积累,最终堆内存就会被占满,导致OOM。 垃圾对象的判定 垃圾对象的判定我们都知道,所谓“垃圾”对象,就是指我们在程序的运行过程中不再有用的对象,即不再存活的对象。那么怎么来判断堆中的对象是“垃圾”、不再存活的对象呢? 引用计数法 引用计数法每个对象都有一个引用计数的属性,用来保存该对象被引用的次数。当引用次数为0时,就意味着该对象没有被引用了,也就不会在使用这个对象了,可以判定为垃圾对象。但是,这种方式有一个很大的Bug,就是无法解决对象间相互引用或者循环引用的问题:当两个对象相互引用,他们两个和其他任何对象也没有引用关系,它俩的引用次数都不为0,因此不会被回收,但实际上这两个对象已经不再有用了。 可达性分析(根搜索法) 为了避免使用引用计数法带来的问题,Java采用了可达性分析法来判断垃圾对象。这种方式可以将所有对象的引用关系想象成一棵树,从树的根节点GC Root遍历所有引用的对象,树的节点就为可达对象,其他没有处于节点的对象则为不可达对象。 那么什么样的对象可以作为GC的根节点呢?虚拟机栈(帧栈中的本地变量表)中引用的对象、方法区中静态属性引用的对象、方法区中常量引用的对象、本地方法栈中JNI引用的对象。 引用状态 垃圾回收机制,不管采用是引用计数法,还是可达性分析法,都与对象的引用有关,Java中存在四种引用状态: 强引用 - 我们使用的大部分引用实际上都是强引用,这是使用最普遍的引用。如果一个对象具有强引用,就表示它处于可达状态,垃圾回收器绝不会回收它,即便系统内存非常紧张,Java虚拟机宁愿抛出 OutOfMemoryError 错误,使程序异常终止,也不会回收被强引用所引用的对象。因此,强引用是造成Java内存泄露的主要原因之一。 软引用 - 一个对象只具有软引用,如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。 弱引用 - 一个对象只具有弱引用,那就类似于是可有可无的。弱引用和软引用很像,但弱引用的引用级别更低。弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。 虚引用 - 一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。虚引用主要用来跟踪对象被垃圾回收的活动,我们平常一般不会使用。 垃圾回收算法 通过可达性分析算法能够判定哪些对象是需要回收的了,那么回收具体需要怎样去执行呢? 标记-清除算法 标记-清除算法首先需要标记可以回收的对象内存,然后在对回收的内存进行清除。但是这样的话,随着程序的运行,会不断分配释放内存,在堆中会产生很多的不连续的空闲内存区,即内存碎片。这样即使有足够多的空闲内存,也不一定能分配出足够大的内存,并且可能会造成频繁的GC,影响效率,甚至OOM。 标记-整理算法 标记-整理算法和标记-清除算法不同的是,标记-整理算法在标记后不直接清理可回收内存,而是将存活对象都移动到一端,然后清除掉可回收内存。这样做的好处就是不会产生内存碎片。 复制算法 复制算法需要先将内存分为两块,先在其中一块内存上分配内存,当这块内存被分配完后,则执行垃圾回收,然后把存活对象全部复制到另一块内存上,第一块内存则全部清空。这种算法不会产生内存碎片,但是相当于只能使用一半的内存空间。同时,复制算法和存活对象的数量有关,如果存活对象的数量多,那么复制算法的效率会大大降低。 分代收集算法 在Java虚拟机中,对象的生命周期有长有短,大部分对象的生命周期很短,只有少部分的对象才会在内存中存留较长时间,因此可以依据对象生命周期的长短将它们放在不同的区域。在采用分代收集算法时,将对象分为新生代和老年代两部分,对新生代对象使用复制算法,对老年代对象使用标记-整理算法或标记-清除算法。























- 粉丝: 9
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- 《Redis 深度历险》学习与实践的笔记整理
- (源码)基于Arduino框架的物品管理库存系统-The Ark.zip
- (源码)基于PythonDjango框架的个人博客网站.zip
- (源码)基于Node.js和Koa框架的电商平台.zip
- (源码)基于Arduino语言的杂项项目.zip
- (源码)基于Arduino的自动浇水系统.zip
- (源码)基于Python和Tkinter的机器人控制界面.zip
- 机器学习、深度学习与自然语言处理等算法的实现示例、博客配套及论文复现
- (源码)基于Spring Boot框架的权限管理系统.zip
- 【51单片机要求:按下按键K3,蜂鸣器响一声,发光二极管D1点亮,再次按下该按键发光二极管D2点亮,注意此时D1依然亮着,依此类推,当第八次接下该安键时,八个发光二极管全部点亮】
- (源码)基于STM32的惯性导航系统.zip
- (源码)基于物联网和MQTT协议的智能垃圾桶监测系统.zip
- (源码)基于物联网的建筑物故障检测与指示系统.zip
- 深度剖析深度学习原理,从零构建专属深度学习库
- 大连理工大学信息检索研究室 2017 年深度学习实践培训内容详情
- 深度学习论文阅读笔记(2013-2018 年)- 研读记录


