使用Java创建内存泄漏 [英] Creating a memory leak with Java

查看:240
本文介绍了使用Java创建内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚接受采访,并被要求用Java创建内存泄漏。
毋庸置疑,我觉得自己很傻,甚至不知道如何开始创建一个。

I just had an interview, and I was asked to create a memory leak with Java. Needless to say I felt pretty dumb having no clue on how to even start creating one.

一个例子是什么?

推荐答案

这是在纯Java中创建真正的内存泄漏(通过运行代码但仍然存储在内存中无法访问的对象)的好方法:

Here's a good way to create a true memory leak (objects inaccessible by running code but still stored in memory) in pure Java:


  1. 应用程序创建一个长时间运行的线程(或者使用线程池来更快地泄漏)。

  2. 线程加载通过(可选自定义)ClassLoader的类。

  3. 该类分配一大块内存(例如 new byte [1000000] ) ,在静态字段中存储对它的强引用,然后在ThreadLocal中存储对它自己的引用。分配额外内存是可选的(泄漏Class实例就足够了),但它会使泄漏工作更快。

  4. 线程清除对自定义类或ClassLoader的所有引用已加载。

  5. 重复。

  1. The application creates a long-running thread (or use a thread pool to leak even faster).
  2. The thread loads a class via an (optionally custom) ClassLoader.
  3. The class allocates a large chunk of memory (e.g. new byte[1000000]), stores a strong reference to it in a static field, and then stores a reference to itself in a ThreadLocal. Allocating the extra memory is optional (leaking the Class instance is enough), but it will make the leak work that much faster.
  4. The thread clears all references to the custom class or the ClassLoader it was loaded from.
  5. Repeat.

这是有效的,因为ThreadLocal保留了对object,它保持对其Class的引用,而Class又保持对其ClassLoader的引用。反过来,ClassLoader保持对它已加载的所有类的引用。

This works because the ThreadLocal keeps a reference to the object, which keeps a reference to its Class, which in turn keeps a reference to its ClassLoader. The ClassLoader, in turn, keeps a reference to all the Classes it has loaded.

(在许多JVM实现中更糟糕,尤其是在Java 7之前,因为类和ClassLoaders直接分配到permgen中,并且根本就没有GC。但是,无论JVM如何处理类卸载,ThreadLocal仍然会阻止Class对象被回收。)

(It was worse in many JVM implementations, especially prior to Java 7, because Classes and ClassLoaders were allocated straight into permgen and were never GC'd at all. However, regardless of how the JVM handles class unloading, a ThreadLocal will still prevent a Class object from being reclaimed.)

此模式的一个变体是,如果您经常重新部署碰巧以任何方式使用ThreadLocals的应用程序,那么应用程序容器(如Tomcat)可能会像筛子那样泄漏内存。 (由于应用程序容器使用了所描述的线程,并且每次重新部署应用程序时都会使用新的ClassLoader。)

A variation on this pattern is why application containers (like Tomcat) can leak memory like a sieve if you frequently redeploy applications that happen to use ThreadLocals in any way. (Since the application container uses Threads as described, and each time you redeploy the application a new ClassLoader is used.)

更新:由于批次人们不断要求它,这里是一些显示此行为的示例代码

Update: Since lots of people keep asking for it, here's some example code that shows this behavior in action.

这篇关于使用Java创建内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆