用于在循环内分配/释放内存的Java垃圾收集器性能

时间:2011-05-24 18:22:24

标签: java memory-management garbage-collection

我有一个程序,其中有问题的循环看起来像这样

int numOfWords = 1000;
int avgSizeOfWord = 20;
while(all documents are not read) {
    char[][] wordsInDoc = new char[numOfWords][avgSizeOfWord];
    for(int i=0; i<numWordsInDoc; i++) {
        wordsInDoc[i] = getNextWord();
    }
    processWords(wordsInDoc);
}

我想知道这个循环执行后场景背后会发生什么。垃圾收集器何时收集为每个文档分配的内存?他们是一个更好的方式(内存使用)做同样的事情吗?

感谢任何见解。

5 个答案:

答案 0 :(得分:4)

一般来说,回答你的问题是不可能的,因为JVM几乎可以做任何关于垃圾收集的事情。

您可以通过在YourKit等内存分析器下运行程序来深入了解实际发生的情况。这也使您能够在内存使用和垃圾收集器中花费的时间方面比较不同的策略(例如,使用String类而不是char数组)。

答案 1 :(得分:3)

嗯,你肯定在浪费内存 - 你要分配所有的“子阵列”然后覆盖它们。你最好用:

while(all documents are not read) {
    char[][] wordsInDoc = new char[numOfWords][];
    for(int i=0; i < numWordsInDoc; i++) {
        wordsInDoc[i] = getNextWord();
    }
    processWords(wordsInDoc);
}

现在processWords实际上做了什么?如果它没有将数组存储在任何地方,那么可以重用它:

char[][] wordsInDoc = new char[numOfWords][];
while(all documents are not read) {
    for(int i=0; i < numWordsInDoc; i++) {
        wordsInDoc[i] = getNextWord();
    }
    processWords(wordsInDoc);
}

我肯定会执行第一次更改,但可能不是第二次更改。

至于何时发生完全垃圾收集 - 这是特定于实现的。

答案 2 :(得分:1)

很可能你正在创建阵列,你正在立即销毁。更有效的方法是创建普通的数组数组,或使用List。

char[][] wordsInDoc = new char[numOfWords][];
for(int i=0; i<numWordsInDoc; i++) {
    wordsInDoc[i] = getNextWord();
}
processWords(wordsInDoc);

OR

List<char[]> wordsInDoc = new ArrayList<char[]>();
for(int i=0; i<numWordsInDoc; i++) {
    wordsInDoc.add(getNextWord());
}
processWords(wordsInDoc);

或使用字符串

String line = "Hello World. This is a Sentence";
String[] words = line.split(" +");
processWords(words);

答案 3 :(得分:0)

垃圾收集器以神秘的方式工作。即使直接调用它也只会产生一个建议。

如果您想知道对象何时被垃圾收集,您可以覆盖finalize()并记录关于时间的输出信息。

答案 4 :(得分:0)

我的几分钱:)。

  1. 我想当你声明一个数组时,与C / C ++不同,你实际上并没有为对象保留内存,但是你可以简单地创建那么多引用。
  2. 每个引用可能占用一定的内存(这将远远低于它所指向的对象所占用的内存)。因此,如果使用普通数组或ArrayList(它以相同的方式执行,但以类型安全的方式),则无关紧要。
  3. 提到的方法的一个基本问题是它将整个文档加载到内存中并将其发送以进行处理。
  4. 更好/更有效的方式将其流出(缓冲),然后即时处理它。这将阻止整个文档加载到内存中。
  5. 关于GC,正如这里的人们指出的那样,无法预测。只要JVM内存不足,它就会启动,但这只是陈词滥调:)。