background image

析 JAVA

 

之垃圾回收机制

 

对于 JAVA 编程和很多类似 C、C++语言有一个巨大区别就是内存不需要自己去 free 或者
delete,而是由 JVM 垃圾回收机制去完成的。对于这个过程很多人一直比较茫然或者觉
得很智能,使得在写程序的过程不太考虑它的感受,其实知道一些内在的原理,帮助我
们编写更加优秀的代码是非常有必要的;本文介绍一些 JVM 垃圾回收的基本知识,后续的
文章中会深入探讨 JVM 的内在;首先在看文章之前大家需要知道为什么要写 JVM 垃圾回
收,在 Java 发展以来,由于需要面向对象,而屏蔽掉程序员对于底层的关心,所以在性
能上存在很多的缺陷,而通过不断改良,很多缺陷已经逐渐的取消掉了,不过还是依然
存在很多的问题,其中最大的一块问题就是 JVM 的垃圾回收机制,一直以来 Java 在设
计实时系统上都被骂声重重,就是因为垃圾回收存在非常多的问题,世界上目前还没有
任何一个垃圾回收机制可以做到无暂停,而只是某些系统可以做到非常少的暂停;本文
还不会讨论那么深入的只是,就简单的内部认识做一些概要性的介绍。
 
本文从以下几个方面进行阐述:
1、finalize()方法
2、System.gc()方法及一些实用方法
3、JAVA 如何申请内存,和 C、C++有何区别
4、JVM 如何寻找到需要回收的内存
5、JVM 如何回收内存的(回收算法分解详述)
6、应用服务器部署及常用参数设置
7、扩展话题 JIT(即时编译技术)与 lazy evaluation(惰性评估),如何在应用服
务器中控制一些必要的信息(小小代码参考)
 
 
1、finalize()方法:
     为了说明 JVM 回收,不得不先说明一个问题就是关于 finalize()方法,所有实体对象
都会有这个方法,因为这个 Object 类定义的,这个可能会被认为是垃圾回收的方法或者
叫做析构函数,其实并非如此。finalize 在 JVM 内存会收前会被调用(单并非绝对),而
即使不调用它,JVM 回收机制通过后面所述的一些算法就可以定位哪些是垃圾内存,那
么这个拿来干什么用呢?finalize()其实是要做一些特殊的内存回收操作,如果对 JAVA
研究稍微多一点,大家会发现 JAVA 中有一种 JNI(Java native interface),这种属于
JAVA 本地接口调用,即调用本地的其他语言信息,JAVA 虚拟机底层掉调用也是这样实
现的,这部分调用中可能存在一些对 C、C++语言的操作,在 C 和 C++内部通过
new、malloc、realloc 等关键词创建的对象垃圾回收机制是无能为力的,因为这不是它
要管理的范围,而平时这些对象可能被 JAVA 对应的实体所调用,那么需要在对应 JAVA
对象放弃时(并不代表回收,只是程序中不使用它了)去调用对应的 C、C++提供的本
地接口去释放这段内存信息,他们的释放同样需要通过 free 或 delete 去释放,所以我
们一般情况下不要滥用 finalize(),个人建议是最好不要用,所有非同类语言的调用不一
定非要通过 JNI 来完成的,或者调用完就直接释放掉相应的内容,而不要寄希望于
finalize 这个方法,因为 JVM 不保证什么时候会调用这个方法。

2、System.gc()或者 Runtime.getRuntime().gc();