![](/img/trans.png)
[英]Java webapp memory leak when using ScheduledExecutorService
[英]Java memory leak when using an array
想确认我的假设。 我正在看另一位使用数组的开发人员的代码,该人正在使用数组(而不是linkedhashset / sorted集合等),并试图根据插入来对其进行排序,但还要将其保持固定大小。 使其保持固定大小的逻辑是从阵列中删除最旧的项目。 但是,当从数组中删除最旧的项时,对象引用不会被清空,即仅将数组索引与另一个对象一起写入。 我认为这可能会使旧的(未清空)对象在内存中的停留时间比需要的时间长(如果没有内存泄漏的话),除非我在范围界定方面错过了任何事情。 任何想法(我也在尝试通过快速测试和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;
}
}
您实际上不需要将引用设置为null即可使其符合垃圾回收的条件。 考虑以下代码段:
Double d = new Double(1.1); // (1)
d = new Double(2.2); // (2)
在第2行,对象句柄“ d”被分配了一个新值。 这意味着值1.1的原始Double现在不再可以以任何方式访问,并且可以进行垃圾回收。 无需先专门写“ d = null”。
Java垃圾收集器将收集所有不再可访问的对象。 您不必取消引用。
ref = null;
ref = newRef;
和
ref = newRef;
具有完全相同的效果,并且,如果没有其他对ref
所指向的对象的ref
,则都将导致垃圾收集器收集该对象。
仅当您要丢弃对对象的引用而不为该引用分配新值时,才需要使引用为空。 在那种情况下,忘记取消引用可能确实会导致内存泄漏,因为仍然存在对您可能不再需要的对象的引用。
但是,当从数组中删除最旧的项时,对象引用不会被清空,即仅将数组索引与另一个对象一起写入。 -这是关键。 将引用设置为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.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.