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

简介:

    首先,根据分享内容,结合 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


 
 
  1. <%@page session="false"%> 
  2. <
  3. int size = (int)(1024 * 1024 * 1); 
  4. byte[] buffer = new byte[size]; 
  5. out.print(buffer); 
  6. <STRONG><SPAN style="COLOR: #ff0000">buffer = null;</SPAN> 
  7.  
  8.  
  9. </STRONG> 
  10.  
  11.  
  12.  
  13. Thread.sleep(50); 
  14. out.print("With statement: buffer = null;"); 
  15. %> 

nonull.jsp


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


 
 
  1. 软件版本: 
  2. Java(TM) SE Runtime Environment (build 1.6.0_10-b33)  
  3. Tomcat 6.0.20  
  4. 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、    将耗时的程序块独立起来, 千万不要将这样的程序快放入大对象的生命周期中.




本文转自 nileader 51CTO博客,原文链接:http://blog.51cto.com/nileader/795517,如需转载请自行联系原作者

相关文章
|
Java Spring
解决Spring工具类BeanUtils copyProperties方法复制null的问题
解决Spring工具类BeanUtils copyProperties方法复制null的问题
940 0
|
4月前
|
SQL 关系型数据库 数据处理
|
6月前
|
Java 数据处理 Apache
探讨Java中判断String类型为空和null的方法
探讨Java中判断String类型为空和null的方法
79 1
|
5月前
|
Java
代码优化设计问题之推荐使用函数式方法进行null判断问题如何解决
代码优化设计问题之推荐使用函数式方法进行null判断问题如何解决
|
6月前
|
Java
Java中判断String类型为空和null的方法
Java中判断`String`变量是否为空或`null`需用`== null`和`.isEmpty()`。示例代码提供两种方法:`main`方法直接判断,`safeGetString`方法提供默认值。当输入为`null`或空时,返回默认值。代码包含三个测试案例,分别处理`null`、空字符串和非空非`null`字符串。
130 0
|
7月前
|
SQL 关系型数据库 MySQL
mysql查询语句的访问方法const、ref、ref_or_null、range、index、all
mysql查询语句的访问方法const、ref、ref_or_null、range、index、all
|
SQL Java 数据库
【Mybatis-plus异常】mybatis-plus updateById方法更新不了空字符串和null的解决方法
【Mybatis-plus异常】mybatis-plus updateById方法更新不了空字符串和null的解决方法
692 0
|
7月前
|
Java
JAVA——List中剔除空元素(null)的三种方法汇总
JAVA——List中剔除空元素(null)的三种方法汇总
|
7月前
|
JSON 前端开发 Java
【SpringBoot实战专题】「开发实战系列」全方位攻克你的技术盲区之Spring定义Jackson转换Null的方法和实现案例
【SpringBoot实战专题】「开发实战系列」全方位攻克你的技术盲区之Spring定义Jackson转换Null的方法和实现案例
131 0
|
前端开发 Java 数据安全/隐私保护
解决通过request.getParam()方法获取到的值为null的问题~
解决通过request.getParam()方法获取到的值为null的问题~
317 0