是否有必要显式的在方法体内将局部变量赋值为null_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 是否有必要显式的在方法体内将局部变量赋值为null

是否有必要显式的在方法体内将局部变量赋值为null

 2011/8/24 8:11:15  yinshi.nc  http://nileader.iteye.com  我要评论(0)
  • 摘要:声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。若作者同意转载,必须以超链接形式标明文章原始出处和作者。上周听了淘宝网技术专家蒋江伟的一个分享《淘宝前台系统优化实践-吞吐量优化》,对其中“编写GC友好的代码”一节颇有兴趣,并存在疑问,回去后反复试验,从网上找资料,在蒋江伟的帮助下,算是得出了自己的结论。首先,根据分享内容,结合PPT摘录了一些基础的东西,FULLGC就是对old区的一次垃圾回收.应用监控中比较关心的。那么究竟谁进入了OLD区呢?对象进入OLD区几个途径
  • 标签:方法

声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。若作者同意转载,必须以超链接形式标明文章原始出处和作者。

????? 上周听了淘宝网技术专家蒋江伟的一个分享《淘宝前台系统优化实践-吞吐量优化》 ? , 对其中“编写GC友好的代码”一节颇有兴趣,并存在疑问,回去后反复试验,从网上找资料,在蒋江伟的帮助下,算是得出了自己的结论。

????? 首先,根据分享内容,结合 PPT 摘录了一些基础的东西, FULL GC 就是对 old 区的一次垃圾回收 . 应用监控中比较关心的。

????? 那么究竟谁进入了OLD区呢? 对象进入OLD区几个途径:第一类是创建的时候直接进入, 这类对象多半是超过指定size的数据,如缓存。第二类比较常见,在minorGC触发的时候,交换分区s0/s1放不下, 向OLD区转移的对象.(就是在Young区创建, 但是生命周期足够长, 并且在s中放不下了).?
????? 对象创建到垃圾回收的步骤简要描述如下:

???????? 1.??? 对象在Eden区完成内存分配.
???????? 2.??? 当Eden区满了, 再创建对象, 会因为申请不到空间, 触发minorGC, 进行young(eden+1survivor)区的垃圾回收.
???????? 3.??? minorGC时,Eden不能被回收的对象被放入到空的survivor(Eden肯定会被清空),另一个survivor里不能被GC回收的对象也会被放入这个survivor,始终保证一个survivor是空的.
???????? 4.??? 当做第3步的时候,如果发现survivor满了,则这些对象被copy到old区,或者survivor并没有满,但是有些对象已经足够Old,也被放入Old区 XX:MaxTenuringThreshold.
???????? 5.??? 当Old区被放满的之后,进行完整的垃圾回收(FULL gc).

????? 好了 ? ,? 现在开始进行测试了 ? . ? 写了如下的测试代码 ? :

???????? 准备两个测试页面:

?

?

Withnull.jsp

?

<%@page session="false"%>
<%
int size = (int)(1024 * 1024 * 1);
byte[] buffer = new byte[size];
out.print(buffer);
buffer = null;




Thread.sleep(50);
out.print("With statement: buffer = null;");
%>
?

?

nonull.jsp

?

<%@page session="false"%>
<%
int size = (int)(1024 * 1024 * 1);
byte[] buffer = new byte[size];
out.print( buffer );
Thread.sleep(50);
out.print("No statement: buffer = null;");
%>

?

?

软件版本:
Java(TM) SE Runtime Environment (build 1.6.0_10-b33) 
Tomcat 6.0.20 
Tomcat启动参数: -Xmx256m -Xmn15m -XX:SurvivorRatio=6
?

?

将两个页面都放在tomcat下, 使用ab进行压测:?
第一个:?? ab? -c20? -n10000? http://localhost/withnull.jsp ?
第二个:?? ab? -c20? -n10000? http://localhost/nonull.jsp

?

?

在执行 第一个压测的时候, 内存与GC情况如下:


?

?

在执行 第二个压测的时候, 内存与GC情况如下:

?

?

由上面的测试可以看到:?
????? 如果程序中显示声明了buffer = null; 那么即使线程在进行sleep的时候, GC仍然可以对那些没有引用的对象进行回收, 所以不需要进入到OLD区了. 于是FGC基本没有. 而如果没有声明的话, 那么在方法调用没有结束前, buffer一直存在, 于是源源不短的buffer对象向old转移, 导致FGC的频繁发生.

???? 另外我们也可以发现, 第二个测试运行一段时间之后, FGC也几乎没有了.(图中一直保持在61), 那这是为什么呢? 我的猜想是JVM进行了实时的优化, 他认为这段程序一直会被运行, 有必要进行优化了. 所以就启动了他的 JIT 优化.?
相关的资料在: http://docs.huihoo.com/javaone/2007/java-se/TS-2906.pdf 这个文档的第17页.

另外, 有几点经验是:?
这个特性不错,上次我们测试的时候也体现出来了。
1、??? 方法内大对象生命周期越短越好,尽量不要跨长时间的方法.
2、??? 将耗时的程序块独立起来, 千万不要将这样的程序快放入大对象的生命周期中.


?

?

  • 大小: 39.2 KB
  • 大小: 84.2 KB
  • 大小: 82.2 KB
  • 大小: 116.6 KB
  • 查看图片附件
发表评论
用户名: 匿名