想证实我的假设。我正在查看另一个使用数组(不是linkedhashset / sorted collection等)的开发人员的代码,并尝试根据插入对其进行排序,同时保持其固定大小。保持固定大小的逻辑是从数组中删除最旧的项目。但是,当从数组中删除最旧的项时,对象引用没有被删除,即只有数组索引被写入另一个对象。我认为这可能会让旧的(没有被淘汰的)对象在内存中停留的时间比需要的时间长(如果不是完全没有内存泄漏),除非我错过任何与范围有关的内容。任何想法(我试图通过快速测试和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;
}
}
答案 0 :(得分:1)
您无需实际设置null引用以使其符合垃圾回收的条件。请考虑以下代码段:
Double d = new Double(1.1); // (1)
d = new Double(2.2); // (2)
在第2行,对象句柄“d”被赋予一个新值。这意味着现在不再以任何方式访问具有值1.1的原始Double,并且有资格进行垃圾回收。没有必要首先专门写“d = null”。
答案 1 :(得分:1)
Java垃圾收集器将收集所有不再可访问的对象。你不必废除引用;
ref = null;
ref = newRef;
和
ref = newRef;
具有完全相同的效果,如果没有对ref
所指向的对象的其他引用,则会导致垃圾收集器收集该对象。
如果要丢弃对对象的引用但不为引用分配新值,则只需要使引用为空。在这种情况下,忘记将引用置空可能确实会导致内存泄漏,因为仍然存在对您可能不再需要的对象的引用。
答案 2 :(得分:0)
但是,从数组中删除最旧的项目时,对象引用没有被删除,即只有数组索引被写入另一个对象。 - 这是关键点。无论您是将引用设置为null还是将其设置为其他对象都无关紧要,如果没有对它的引用,则“原始”对象将无法访问。
示例:
arr[0] = new myObject();
MyObject my = arr[0];
arr[0]=null; // or arr[0] = new myObject(); makes no difference. Since The original MyObject is still reachable, it will not be considered for GC.
my=null; // or my=new MyObject() // now the original MyObject instance will be unreachable and hence ready for GC.