当以(显然)不正确的方式使用时,哪些类的Java Standard API会导致内存泄漏?如何避免/修复这些内存泄漏?
示例: ObjectInputStream
并ObjectOutputStream
保留对他们所见过的所有对象的引用,以便发送与引用相同的对象的后续出现而不是副本(从而处理循环引用).当您无限期地保持此类流(例如,当使用它通过网络进行通信时)时,这会导致内存泄漏.
修复:定期或在每个顶级对象之后调用reset().
一个重要的问题是获取Java字符串的子字符串是指原始字符串.
示例:您读入3000个字符的记录并获取12个字符的子字符串,并将其返回给调用者(在同一个JVM中).即使您没有直接引用原始字符串,该12个字符的字符串仍在内存中使用3000个字符.
对于接收然后解析大量消息的系统,这可能是一个真正的问题.
您有两种方法可以避免这种情况:
String sub = new String(str.substring(6,12));
要么
String sub = str.substring(6,12).intern();
第一个是更明确的.第二个有其他影响,因为你正在使用PermGen空间.过度使用你可能会用完,除非你给你足够的VM.
请记住,这只有在您使用小的子串然后丢弃原始字符串并且您正在执行此操作时才有意义.
您注册为事件接收者的所有内容(例如在GUI框架中)只要已注册且事件源处于活动状态,就无法进行垃圾回收.
如果开发人员不知道从事件源到事件订阅者的强引用,则可能会引入内存泄漏.
您使用的任何非静态内部类都保留在外部类中.因此,无辜的内部类可以保持一个巨大的对象图.将实例放在某个静态或应用程序范围的集合中,并且您正在使用大量不应该使用的内存.
线程的每个实例化都为堆栈分配内存(默认为512k,可调整通道-Xss
).这不是一个泄漏这样的,但天真的企图大量多线程的应用程序将导致内存相当大的非显而易见的消耗.