Java编程思想-终结处理和垃圾回收

关于垃圾回收要知道三点:

  1. 对象可能不被垃圾回收
  2. 垃圾回收并不等于“析构”
  3. 垃圾回收只与内存有关

垃圾回收器如何工作?

可以将对想象成一个传送带,每分配一个对象,传送带就往前移动一格,然而这样的弊端是会造成频繁的内存页面调度(将其移进移出硬盘)进而影响性能,当创建了足够多的对象之后,内存资源耗尽。但当垃圾回收器介入后,它一边工作一边回收空间,使得堆中的对象紧凑排列,这样“堆指针”很容易移动到传送带的开始处,也就避免了页面错误。通过垃圾回收器对对象的重新跑列,实现一种高效,有无限空间可供分配的堆模型。

垃圾回收机制:引用计数,停止复制,标记-清扫

  1. 引用计数器是一种很慢的垃圾回收技术,每个对象都含有一个引用计数器,当有引用连接至对象时,引用计数加1,当引用离开作用域或被置为null时,引用计数减1。垃圾回收器一旦发现某个对象的引用计数为0时,就释放其占用的内存。这种方法有一个弊端就是,当对象之间出现循环引用时,这种情况下,引用计数不为零,而垃圾回收器应该回收该对象的情况
  2. 停止复制是先要暂停程序的运行,然后将所有存活的对象从当前堆复制到另一个堆,没有复制的对象将不再存活,复制到新堆的对象会一个挨着一个在空间上紧凑排列,这种垃圾回收技术的效率通常很低,原因有两个:首先得有两个堆,这意味着得维护比实际多一倍的内存空间;其次当程序进入稳定状态后,可能在产生很少的垃圾时,该垃圾回收器也要将存活的对象从一处复制到另一处,这样做会很浪费,因此引出了标记-清扫模式
  3. 标记-清扫所依据的思路是从堆栈和静态存储区触发,遍历所有的引用,进而找出所有存活的对象,每当找到一个存活的对象就会给该对象设定一个标记,但这一过程不会回收任何对象,当所有标记工作完成以后,清扫工作才会开始,在清扫过程中,没有标记的对象将会被释放,不会发生复制动作,所以剩下的空间是不连续的,垃圾回收器想要得到连续内存空间的话,就需要重新整理剩下的对象

Java虚拟机中采用自适应的,分代的,停止复制,标记-清理的垃圾回收模式

HotSpot中采用“惰性评估”的方式来提升速度,意思是即时编译器只在必要的时候才编译代码, 这样,从不会被执行的代码也许压根就不会被JIT编译,这样执行的次数越多,它的速度就越快

猜你喜欢

转载自blog.csdn.net/wo8vqj68/article/details/84972227
今日推荐