垃圾收集机制(Garbage Collection)批判
在Java版发表这篇文章,似乎有点把矛头指向Java了。其实不是,GC是所有新一代语言共有的特征,
Python, Eiffel,C#,Roby等无一例外地都使用了GC机制。但既然Java中的GC最为著名,所以天塌
下来自然应该抗着。
这篇短文源于comp.lang.java.programmer跟comp.lang.c++上发生的一场大辩论,支持C++和Java
的两派不同势力展开了新世纪第一场冲突,跟贴发言超过350,两派都有名角压阵。C++阵营的擂主是
Pete Becker,ACM会员,Dinkumware Ltd. 的技术副总监。此君精通C++和Java,开发过两种语言的
核心类库,但是却对C++狂热之极,而对于Java颇不以为然。平时谈到Java的时候还好,一旦有人胆
敢用Java来批判C++,立刻忍不住火爆脾气跳将出来,以坚韧不拔的毅力和大无畏精神与对手周旋,
舌战群儒,哪怕只剩下一个人也要血战到底。这等奇人当真少见!我真奇怪他整天泡在usenet上,
不用工作么?他的老板P.J. Plauger如此宽宏大量?Java阵营主角是一个网名Razzi的兄弟,另外有
Sun公司大名鼎鼎的Peter van der Linden助阵,妙语连珠,寸土必争,加上人多势众,一度占据优势。
C++阵营里大拿虽然很多,但是大多数没有Pete那么多闲工夫,例如Greg Comeau,Comeau公司老板,
每次来个只言片语,实在帮不了Pete多大忙。但是自从C++阵营中冒出一个无名小子,网名Courage(勇气),
发动对Java GC机制的批判,形势为之一变。C++阵营眼下处于全攻之势,Java阵营疲于防守,只能
招架说:“你们没有证据,没有统计资料”,形势很被动。
垃圾收集(GC)不是一直被Java fans用来炫耀,引以为傲的优点么?怎么成了弱点了?我大惑不解,定睛
一看,才觉得此中颇有道理。
首先,Java Swing库存在大量资源泄漏问题,这一点SUN非常清楚,称之为bugs,正在极力修正。但是看来
这里的问题恐怕不仅是库编写者的疏忽,可能根源在于深层的机制,未必能够轻易解决,搞不好要伤筋动骨。
不过这个问题不是那么根本,C++阵营觉得如果抓住对方的弱点攻击,就算是占了上风也没什么说服力。谁
没有缺点呢?于是反其道而行之,猛烈攻击Java阵营觉得最得意的东西,Java的GC机制本身。
首先来想一想,memory leak到底意味着什么。在C++中,new出来的对象没有delete,这就导致了memory
leak。但是C++早就有了克服这一问题的办法——smart pointer。通过使用标准库里设计精致的auto_ptr
以及各种STL容器,还有例如boost库(差不多是个准标准库了)中的四个smart pointers,C++程序员只要
花上一个星期的时间学习最新的资料,就可以拍着胸脯说:“我写的程序没有memory leak!”。
相比之下,Java似乎更优秀,因为从一开始你就不用考虑什么特殊的机制,大胆地往前new,自有GC替你
收拾残局。Java的GC实际上是JVM中的一个独立线程,采用不同的算法策略来收集heap中那些不再有
reference指向的垃圾对象所占用的内存。但是,通常情况下,GC线程的优先级比较低,只有在当前程序
空闲的时候才会被调度,收集垃圾。当然,如果JVM感到内存紧张了,JVM会主动调用GC来收集垃圾,获取
更多的内存。请注意,Java的GC工作的时机是:1. 当前程序不忙,有空闲时间。2. 空闲内存不足。
现在我们考虑一种常见的情况,程序在紧张运行之中,没哟空闲时间给GC来运行,同时机器内存很大,
JVM也没有感到内存不足,结果是什么?对了,GC形同虚设,得不到调用。于是,内存被不断吞噬,而那些
早已经用不着的垃圾对象仍在在宝贵的内存里睡大觉。例如:
class BadGc {
public void job1() {
String garbage = "I am a garbage, and just sleeping in your precious memory, " +
"how do you think you can deal with me? Daydreaming! HAHA!!!";
....
}
public void job2() {...}
...
...
public void job1000() {...}
public static void main(String[] args) {
bgc = new BadGc();
bgc.job1();
bgc.job2();
...
bgc.job1000();
}
}
运行中,虽然garbage对象在离开job1()之后,就再也没有用了。但是因为程序忙,内存还够用,所以GC得
不到调度,garbage始终不会被回收,直到程序运行到bgc.job1000()时还躺在内存里嘲笑你。没辙吧!
好了,我承认这段程序很傻。但是你不要以为这只是理论上的假设,恰恰相反,大多数实用中的Java程序都有
类似的效应。这就是为什么Java程序狂耗内存,而且好像给它多少内存吃都不够。你花上大笔的银子把内存
从128升到256,再升到512,结果是,一旦执行复杂任务,内存还是被轻易填满,而且多出来的这些内存只是
用来装垃圾,GC还是不给面子地千呼万唤不出来。等到你的内存终于心力交瘁,GC才姗姗来迟,收拾残局。而
且GC工作的方式也很不好评价,一种方法是一旦有机会回收内存,就把所有的垃圾都回收。你可以想象,这要
花很长时间(几百M的垃圾啊!),如果你这时侯正在压下开炮的按钮,GC却叫了暂定,好了,你等死吧!另一
种方法,得到机会之后,回收一些内存,让JVM感到内存不那么紧张时就收手。结果呢,内存里始终有大批垃
圾,程序始终在半死不活的荡着。最后,GC可以每隔一段时间就运行一次,每次只回收一部分垃圾,这是现在
大部分JVM的方式,结果是内存也浪费了,还动不动暂停几百毫秒。难啊!
反过来看看C++利用smart pointer达成的效果,一旦某对象不再被引用,系统刻不容缓,立刻回收内存。这
通常发生在关键任务完成后的清理(cleanup)时期,不会影响关键任务的实时性,同时,内存里所有的对象
都是有用的,绝对没有垃圾空占内存。怎么样?传统、朴素的C++是不是更胜一筹?
据统计,目前的Java程序运行期间占用的内存通常为对应C++程序的4-20倍。除了其它的原因,上面所说的是一个
非常主要的因素。我们对memory leak如此愤恨,不就是因为它导致大量的内存垃圾得不到清除吗?如果有了
GC之后,垃圾比以前还来势汹汹,那么GC又有什么好处呢?
当然,C++的smart pointer现在会使用的人不多,所以现在的C++程序普遍存在更严重的memory leak问题。
但是,如果我奶奶跟舒马赫比赛车输掉了,你能够埋怨那辆车子么?
分享到:
相关推荐
书围绕着动态内存自动回收的话题,介绍了垃圾收集机制,详细分析了各种算法和相关技术。 本书共12章。第1章首先介绍计算机存储器管理的演化和自动内存回收的需求,并引入了本书所使用的术语和记法。第2章介绍了3...
The Garbage Collection Handbook The Art of Automatic Memory Management, Jones, Hosking, Moss, 2012
The Garbage Collection Cookbook 垃圾回收算法手册
The Garbage Collection Handbook:The Art of Automatic Memory Manage
The Garbage Collection Handbook 内存管理,垃圾收集,GC
The Garbage Collection Handbook 关于垃圾回收器算法的书籍,非常不错
细述 Java垃圾回收机制→How Java Garbage Collection Works- - Android 1
The Garbage Collection Handbook The Art of Automatic Memory Management 英文epub
书围绕着动态内存自动回收的话题,介绍了垃圾收集机制,详细分析了各种算法和相关技术。 本书共12章。第1章首先介绍计算机存储器管理的演化和自动内存回收的需求,并引入了本书所使用的术语和记法。第2章介绍了3...
本书围绕着动态内存自动回收的话题,介绍了垃圾收集机制,详细分析了各种算法和相关技术。 本书共12章。第1章首先介绍计算机存储器管理的演化和自动内存回收的需求,并引入了本书所使用的术语和记法。第2章介绍了3...
Java Garbage Collection Study java 垃圾回收学习
Garbage Collection Algorithms For Automatic Dynamic Memory Management
Java Garbage Collection Basics
说起垃圾收集(Garbage Collection,GC),大部分人都把这项技术当做Java语言的伴生产物。经过半个世纪的发展,内存的动态分配与内存回收技术已经相当成熟,一切看起来都进入了“自动化”时代,那为什么我们还要去...
WP - Understanding Java Garbage Collection(了解Java垃圾收集).pdf WP - C4(C4:连续并发压缩收集器).pdf WP - JVM Performance Study(JVM性能研究使用Apache Cassandra™比较OracleHotSpot®和AzulZing®).pdf
The Java Platform, Standard Edition HotSpot Virtual Machine Garbage Collection Tuning Guide describes the garbage collection methods included in the Java HotSpot Virtual Machine (Java HotSpot VM) and ...
严蔚敏数据结构与算法▲课本算法实现
垃圾收集GC(Garbage Collection)是Java语言的核心技术之一,之前我们曾专门探讨过Java 7新增的垃圾回收器G1的新特性,但在JVM的内部运行机制上看,Java的垃圾回收原理与机制并未改变。垃圾收集的目的在于清除不再...
在JVM5.0中调配Garbage Collection 在JVM5.0中调配Garbage Collection 在JVM5.0中调配Garbage Collection
WP-Understanding Java Garbage Collection