我有一个程序,其中有问题的循环看起来像这样
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);
}
我想知道这个循环执行后场景背后会发生什么。垃圾收集器何时收集为每个文档分配的内存?他们是一个更好的方式(内存使用)做同样的事情吗?
感谢任何见解。
答案 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)
我的几分钱:)。
关于GC,正如这里的人们指出的那样,无法预测。只要JVM内存不足,它就会启动,但这只是陈词滥调:)。