JAVA垃圾回收机制

    java中提供了垃圾回收器(简称gc),对于不再使用的内存能自动将其释放。那gc是怎么工作的呢?
    居然要垃圾回收,那么就要定位什么是“垃圾”。在JAVA里面认为对任何“活”的对象,都能追溯到其在堆栈区或静态存储区的引用,简称“活对象”,简单点来说就是有对象引用指向它。那么怎么找出所有的“活对象”呢?就是从堆栈和静态存储区出发遍历所有的对象引用,定位引用指向的对象,该对象中包含的所有对象引用,如此反复进行就找出了所有的活对象。其余的就被当作垃圾处理。
      垃圾回收一般有两种方式,一是“停止-复制”,二是“标记-清扫”。
    “停止-复制”,就是停止当前运行的程序,把当前所有“活对象”从当前堆复制到另一个堆,然后修正对象引用。这个方法有个好处就是新堆里的对象排列紧凑,有利于分配新的内存。但缺点也很明显,那就是动作太大,需要多一倍的空间。另外对于运行稳定的程序,只会产生很少的垃圾,用这种方式就很浪费。
    “标记-清扫”,就是对于所有的活对象,给它一个标记,未标记的则被释放。这个缺点就是清扫后的堆空间不连续的,但是它在只产生少量垃圾的时候效率很高。
    可以看出上面的两种方式是互补的,所以java虚拟机gc的工作是自适应的。也就是说Jvm会对其进行跟踪,如果所有对象都很稳定,gc工作效率降低就转换到“标记-清扫”方式,如果堆空间出现很多碎片,就会切换到“停止-复制”方式。另外,jvm内存分配方式是以“块”为单位的,较大的对象会单独占有块。大型对象仍然不会被复制,内含小型对象的则会被复制并整理。
    一个很重要的问题就是gc只会释放那些用new分配的内存,当JIN时,比如说调用了C语言,那么C用malloc分配的内存就无能为力了。这时fanalize()就出现了,它的工作原理是这样的:一旦垃圾回收机制准备好释放某个对象占用的内存控件时,将会首先调用finalize()方法,当垃圾回收发生时,就会真正回收对象占有的内存。所以用finalize()方法就可以在垃圾回收时刻做一些重要的清理工作。垃圾回收只跟内存有关,所以 finalize()的清理也应该只跟内存有关。
    但是垃圾回收机制也是需要资源的,所以不是必要时刻(濒临存储空间用完),垃圾回收不会发生。也就是说finalize()方法并不会保证被调用。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值