2012-07-25 206 views
3

我有两个函数,一个是insert(),另一个是startGC()。为什么Java System.gc()不能按预期工作?

我会先调用insert()方法,这将花费大约300MB的堆空间。 之后,我将调用startGC(),它应该释放堆中分配的内存,因为所有的矢量对象都是该函数的本地对象,但它不会发生。

private void insert() 
{ 
     Vector v=new Vector(); 
     Vector v1=new Vector(); 
     Vector v2=new Vector(); 
     String str="Hello"; 

     for (long i = 0L; i < 999999L; i++) { 
      v.add(str + i); 
      v1.add(str + i); 
      v2.add(str + i); 
     } 
     v=null; 
     v1=null; 
     v2=null; 
} 

private void startGC() 
{ 
    System.gc(); 
} 

我的问题:

1)为什么垃圾收集不是在这个例子中工作。

2)如何让JVM垃圾收集所有未使用的内存块。

任何代码示例实现相同。

+1

你怎么知道它不工作? – Mob 2012-07-25 14:19:07

+0

您使用的是什么jvm? – poussma 2012-07-25 14:33:35

回答

1

如前所述,您只能建议GC删除您的对象。你可能做的唯一的事情是设置heapmax(例如:-Xmx512m)。这样可以影响gc的运行。 这可能是Java的最大缺点之一。如果你真的需要堆,你必须使用像cpp这样的语言,它不会使用虚拟机来编译应用程序。

7
  1. 以何种方式不起作用?
  2. 你不能告诉的JVM启动垃圾收集,你只能建议,你认为它是通过调用的System.gc一个好主意()。

JavaDoc

调用gc方法表明Java虚拟机了一些努力,以使他们目前占据可快速重用的内存回收未使用的对象。当控制从方法调用返回时,Java虚拟机已尽最大努力从所有被丢弃的对象中回收空间。

+0

它没有释放分配的内存。 – Vasant 2012-07-25 14:20:11

+0

你读过他说的吗? – funkybro 2012-07-25 14:21:30

+0

@Vasant:尽管它有希望花费回收内存,但很难验证它没有。 – Keppil 2012-07-25 14:21:33

1

This是一个很好的阅读Java垃圾收集。

2

如果我尝试

private static void insert() { 
    List<String> v1 = new ArrayList<>(), v2 = new ArrayList<>(), v3 = new ArrayList<>(); 
    String str = "Hello"; 

    for (long i = 0L; i <= 999999; i++) { 
     v1.add(str + i); 
     v2.add(str + i); 
     v3.add(str + i); 
    } 
} 

private static void startGC() { 
    System.gc(); 
} 

private static long mbUsed() { 
    return (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024/1024; 
} 

public static void main(String... args) { 
    startGC(); 
    System.out.printf("Memory used before insert %,d MB%n", mbUsed()); 
    insert(); 
    System.out.printf("Memory used after insert %,d MB%n", mbUsed()); 
    startGC(); 
    System.out.printf("Memory used after GC %,d MB%n", mbUsed()); 
} 

它打印

​​

所以它似乎为我工作。

1

您不能强制收集,这是错误的方法。您应该了解可以传递给JVM的不同垃圾收集参数,并选择能够最大化您感兴趣的性能(总吞吐量?最小暂停?等)的那些参数。代码本身不应该担心gc。

相关问题