java虚拟机垃圾回收

最近在读《java编程思想》,读到垃圾回收,作一下笔记,也供大家参考。

1、Object中的finalize()方法

java的垃圾回收器只知道释放由new()分配的内存,不知道如何释放那些没有使用new创建的对象。java在基类中定义了一个finalize()方法,它的工作原理“假定”为:一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用finalize()方法,并且在下一次垃圾回收动作发生时,才会真正回收对象占用的空间。

但是,java中的对象并非总被回收。只要程序没有濒临存储空间用完的时候,对象占用的空间就总也得不到释放。因为垃圾回收本身也有开销,要是不使用它,就不用支付这部分开销。

2、finalize()用途

首先,不应该将finalize()作为通用的清理方法。

垃圾回收只与内存有关。无论对象时如何创建的,垃圾回收器都会负责释放对象占据的所有内存。finalize()的使用被限制到一种特殊情况:

本地方法:java中调用非java代码的方式,本地方法目前只支持C和C++.

调用本地方法分配的内存空间,需要在finalize()中用本地方法调用清理内存函数(比如free())。。所以不要过多使用finalize()。

java虚拟机(JVM)如果并未面临内存耗尽的情况,是不会浪费时间去执行垃圾回收的。

System.gc()用于强制终结动作。

3、垃圾回收

垃圾回收工作时,将一面回收空间,一面使堆中的对象紧凑排列,这样“堆指针”就可以很容易移动到更靠近传送带的开始处,也就尽量避免了页面错误。通过垃圾回收器对对象的重新排列,实现了一种高速的、有无限空间可供分配的堆模型。

      3.1 引用计数法

引用计数法是一种简单但是速度很慢的垃圾回收技术。每个对象都有一个计算器,当有引用连接至对象时,引用计数+1,当引用离开作用域或者被置为null时,引用计数-1.虽然管理引用计数的开销不大,但是这项开销在真个程序生命周期中持续发生。垃圾回收器会在含有全部对象的列表上遍历,当发现某个对象的引用计数为0时,就释放其占用的空间。但是这种方法有个缺陷,就是对象之间的存在循环引用,会出现问题,对象该被回收,但是计数不等于0.【该方法从未被应用于任何一种java虚拟机实现】

3.2 GC-Root模式 

该模式依据的思想:对任何“活”的对象,一定能最终追溯到其存活在堆栈或静态存储区之中的引用。由此,如果从堆栈和静态存储区开始,遍历所有的引用,就能找到所有“活”的对象。

在这种方式下,java虚拟机将采用一种自适应的垃圾回收技术。至于如何处理找到的存活对象,取决于不同的java虚拟机实现。有两种方法实现该模式:

【停止-复制(stop-copy)】

该方法需要先暂停程序的运行(所以不属于后台回收模式),然后将所有存活的对象从当前堆复制到另一个堆,没有被复制的全部都是垃圾。当对象被复制到新堆时,它们是一个挨着一个的,所以新堆保持紧凑排列。然后可以简单、直接分配内存空间了。

但是该模式效率低。原因有两个。首先,得有两个堆,然后在这两个分离的堆之间来回倒腾,从而维护比实际多一倍的空间。某些java虚拟机堆此问题处理方式是:按需从堆中分配几块大的内存,复制动作发生在这些大块内存中。第二个问题,程序在稳定后,可能只会产生少量的垃圾,甚至没有垃圾,但是依然会执行该模式,造成浪费。

所以一些java虚拟机会进行检查:要是没有新垃圾产生,就会转换到另一种工作模式:标记-清除(mark-and-sweep)。

【标记-清除(mark-and-sweep)

从堆栈和静态存储区出发,遍历所有的引用,进而找出所有的对象。每当找到一个存活对象,就会给对象设一个标记,这个过程不会回收任何对象。只有全部标记工作完成的时候,清理动作才会开始。清理过程中,没有标记的对象会释放,不会发生任何复制动作。所以剩下的堆空间是不连续的,垃圾回收器要是希望得到连续空间,就得重新整理剩下的对象 。该模式工作也必须在程序暂停的情况下才能进行。

最终,java虚拟机将采用一种自适应的垃圾回收技术。java虚拟机会进行监视,如果所有对象都很稳定,垃圾回收器的效率降低的话,就切换到“标记-清除”方式。同样,java虚拟机会跟踪‘“标记-清除”的效果,要是堆空间出现很多碎片,就会切换到“停止-复制”方式。

参考《java编程思想  Thinking in Java》

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值