我最近参加了一次面试,其中被要求使用Java创建一个内存泄漏。
不用说,我感到很笨,因为我不知道如何开始创建。
你可以给一个例子吗?
我最近参加了一次面试,其中被要求使用Java创建一个内存泄漏。
不用说,我感到很笨,因为我不知道如何开始创建。
你可以给一个例子吗?
在finalize方法中抛出未处理的异常。
public static final ArrayListWrapper wrapperClass = new ArrayListWrapper()
)。因此,引用不能被改变。也就是说,wrapperClass = null
不起作用,不能用于释放内存。但是,除了向其中添加对象之外,没有任何方式可以处理wrapperClass
。因此,您向wrapperClass
添加的任何对象都无法回收利用。Swing对话框的使用非常简单。创建一个JDialog,展示它,用户关闭它,就完成了!
您需要调用dispose()
或配置setDefaultCloseOperation(DISPOSE_ON_CLOSE)
。
在具有自己的生命周期的类中粗心地使用非静态内部类。
在Java中,非静态内部类和匿名类都持有对其外部类的隐式引用。而静态内部类则没有。
以下是一个在Android中可能导致内存泄漏的常见示例,尽管不太明显:
public class SampleActivity extends Activity {
private final Handler mLeakyHandler = new Handler() { // Non-static inner class, holds the reference to the SampleActivity outer class
@Override
public void handleMessage(Message msg) {
// ...
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Post a message and delay its execution for a long time.
mLeakyHandler.postDelayed(new Runnable() {//here, the anonymous inner class holds the reference to the SampleActivity class too
@Override
public void run() {
//....
}
}, SOME_TOME_TIME);
// Go back to the previous Activity.
finish();
}}
mLeakyHandler
设置为静态变量可以防止内存泄漏吗?还有没有其他方法可以防止mLeakyHandler
导致Activity内存泄漏?
此外,您如何解决匿名的Runnable
内部类的相同问题? - ban-geoengineering失效的监听器是内存泄漏的一个很好的例子:对象被添加为监听器。当不再需要该对象时,所有对该对象的引用都将被置空。然而,如果忘记从监听器列表中删除该对象,则会使该对象保持活动状态并响应事件,从而浪费内存和CPU资源。请参见http://www.drdobbs.com/jvm/java-qa/184404011
subList()
让我们检查一些非常愚蠢的代码来产生泄漏。public class MemoryLeak {
private static final int HUGE_SIZE = 10_000;
public static void main(String... args) {
letsLeakNow();
}
private static void letsLeakNow() {
Map<Integer, Object> leakMap = new HashMap<>();
for (int i = 0; i < HUGE_SIZE; ++i) {
leakMap.put(i * 2, getListWithRandomNumber());
}
}
private static List<Integer> getListWithRandomNumber() {
List<Integer> originalHugeIntList = new ArrayList<>();
for (int i = 0; i < HUGE_SIZE; ++i) {
originalHugeIntList.add(new Random().nextInt());
}
return originalHugeIntList.subList(0, 1);
}
}
实际上,我们可以利用HashMap的查找过程来造成内存泄漏的另一个技巧。它实际上有两种类型:
hashCode()
总是相同,但equals()
不同;hashCode()
和equals()
始终为true;为什么?
hashCode()
-> bucket => equals()
用于定位键值对
我本来要先提到 substring()
,然后再用 subList()
,但好像这个问题在JDK 8中已经修复了,因为它的源代码已经存在。
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > value.length) {
throw new StringIndexOutOfBoundsException(endIndex);
}
int subLen = endIndex - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
return ((beginIndex == 0) && (endIndex == value.length)) ? this
: new String(value, beginIndex, subLen);
}