【发布时间】:2015-02-24 15:14:14
【问题描述】:
想证实我的假设。我正在查看另一个开发人员的代码,该开发人员正在使用数组(不是linkedhashset/排序集合等),并试图根据插入对其进行排序,同时保持它的大小固定。保持它固定大小的逻辑是从数组中删除最旧的项目。但是,当从数组中删除最旧的项目时,对象引用并没有被清空,即只有数组索引被写入另一个对象。我认为这可能会让旧的(未清空的)对象在内存中停留的时间比需要的时间长(如果不是完全内存泄漏的话),除非我错过了范围界定的任何内容。任何想法(我也在尝试通过快速测试和 visualvm 来确认)。提前致谢。
public class MemTest {
private TestBuffer testQuotes = new TestBuffer(10); //static inner class
public static void main(String[] args) {
System.out.println("Starting!");
MemTest memTest = new MemTest();
for (int j = 0; j < 10; j++) {
for (int i = 0; i < 2000000000; i++) {
memTest.testQuotes.push(1, 12.3);
}
try {
Thread.sleep(2000);
}
catch (InterruptedException e) {
System.out.println("exception:" + e);
}
}
}
private static class QuoteBuffer {
private Object[] keyArr;
private Price[] testArr;
public TestBuffer(int size) {
keyArr = new Object[size];
testArr = new Price[size];
}
public Price get(Object key) {
if (key != null) {
for (int i=0; i<keyArr.length; i++) {
if ( key.equals(keyArr[i]) )
return quoteArr[i];
}
}
return null;
}
private void _slideTestQuotes() {
Object prevKey = null;
Price prevQuote = null;
Object tempKey;
Price tempQuote;
for (int i=0; i<keyArr.length; i++) {
// slide key to the next index
tempKey = keyArr[i];
keyArr[i] = prevKey;
prevKey = tempKey;
// tempKey = null; //I am guessing uncommenting this should make a difference
// slide quote to the next index
tempQuote = quoteArr[i];
quoteArr[i] = prevQuote;
prevQuote = tempQuote;
// tempQuote= null; //I am guessing uncommenting this should make a difference
}
}
public void push(Object key, Double quote) {
_slideTestQuotes();
keyArr[0] = key;
quoteArr[0] = new Price(quote); //quote;
}
}
public class Price {
Double price;
Double a1;
Double a2;
Double a3;
Double a4;
Double a5;
Double a6;
Price(Double price) {
this.price = price;
this.a1 = price;
this.a2 = price;;
this.a3 = price;
this.a4 = price;
this.a5 = price;
this.a6 = price;
}
}
【问题讨论】:
-
Java 有一个 GC。您需要非常努力地解决内存泄漏,对象不必为了被收集而“无效”,它只需要不可访问。
-
只要没有对它的引用,您就不必将对象清空。还要记住
Double!=double... -
你有什么问题?你遇到 OutOfMemoryError 了吗?
-
欢迎使用无需自己管理内存的 Java。不,您不需要将临时变量设置为 null,并且此代码不会导致内存泄漏。
-
我知道 Double != double - 我只是在几分钟内写了这个来测试。我了解参考部分(这就是我在帖子中提到范围的原因)。我认为(根据我的帖子)不清空数组中的对象可能会导致对象停留更长时间,而不是在年轻代中被收集,而是被迁移到 s0/s1 甚至可能是老一代。我正在寻找的应用程序正在经历太多的旧集合(我没有等效的测试环境来测试这个,而且如果没有足够强大的案例,我无法进行产品更改)。
标签: java memory-leaks