java内存回收问题个人档案

java内存回收问题个人档案

第一看一下下面两段落代码来啊界别:

{
    new A().test();
} 

{
    A a = new A();
    a.test();
}

随即失去咨询大家项目首席执行官,他坚持不渝看就简单栽办法是一样的,个人习惯差造成的例外写法而已。就功效及的话,都调用了test()函数,确实没什么区别,可是,虽然考虑了内存回收,这半种植写法就发生分外可怜之异。
个人档案,俺们好拿这事例更有血有肉一点,如下:

{
    //mark 1
    new A().test();
    //mark 2
    new A().test();
    //mark 3
    .....
}

先是种写法,在mark2处,A的内存已经可以吃提交垃圾回收器回收了,也就是说在mark2处,可用内存和mark1高居的可用内存完全相同。

{
    //mark 1
    A a = new A();
    //mark 2
    A b = new A();

    a.test();
    b.test();
}

次栽写法在mark
2处的可用内存和mark1远在之可用内存是殊的,即便A类应用异常死之上空,那么在mark2这里汇合放任来内存溢出卓殊,相反,第一栽写法却尚无这种问题。
脚的测试代码申明了少于种植写法的区分

class MemoryTest
{
 int a[] = new int[10 * 1024 * 1024 * 10];
 static int b = 0;

 MemoryTest()
 {
  b++;
  a[0] = a[1] = 2;
 }

 void Test()
 {
  System.out.println("12345 + " + b); 
 }
}

public class TestJava
{
 public static void main(String[] args)
 throws Exception
 {
  //works well
  new MemoryTest().Test();

  //the gc collected the memory so it can be reuse
  new MemoryTest().Test();

  MemoryTest c = new MemoryTest();

  //if cancel this comment, there will be a memory exception
  //that means there's not enough memory for d
  /*MemoryTest d = new MemoryTest();*/

  System.out.println("end test");
 }
}

造成这种问题,紧要仍然java的内存回收机制,当java发现可用内存不足时,会调用内存回收器,内存回收器会失去遍历当前线程栈,然后因栈中的援确定当前受运用的内存,将尚未受遍历到之内存释放,在下边的事例中,b处于栈上,不可能让回收,因而当c申请新内存是颇。b和c指向的内存要赶有了功用域(如今之大括号)才好让回收。
此问题化解后,登时还要来一个新的题材,第一种写法被我们调用 new
A().test();
即便是函数执行时老丰裕,怎样保管在推行进程中A的内存不谋面让回收(没有显式处于栈上的援指向)。
设想到c++的现变量,所以估算java的编译器会将new
A().test();这段代码做如下处理:

{
   {
        //mark 1
        A temp = new A();
        temp.test();
   }
   //mark 2
}

以mark1地处,从栈上分配temp引用指向堆着之A,之后,在mark2处,由于temp离开他协调的成效域,则栈上内存释放,也就是说栈上不再具备指向A的援,使得A内存可被回收。

结论
推介应用 new A().test();这样的写法,在必然水准达可节约当前内存。
(原文时间2013-1-30)

admin

网站地图xml地图