Java 标准 API 中的内存泄漏陷阱 [英] Memory leak traps in the Java Standard API

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

问题描述

Java 标准 API 的哪些类在以(不明显)不正确的方式使用时会导致内存泄漏?以及如何避免/修复这些内存泄漏?

示例: ObjectInputStreamObjectOutputStream 保留对它们所看到的所有对象的引用,以便将同一对象的后续出现作为引用发送而不是而不是副本(从而处理循环引用).当您无限期地保持这样的流打开时(例如,当使用它通过网络进行通信时),这会导致内存泄漏.

Example: ObjectInputStream and ObjectOutputStream keep references to all objects they have seen in order to send subsequent occurences of the same object as references rather than copies (and thereby deal with circular references). This causes a memory leak when you keep such a stream open indefinitely (e.g. when using it to communicate over the network).

修复:定期或在每个顶级对象之后调用 reset().

Fix: Call reset() periodically or after each top-level object.

推荐答案

一个很大的问题是获取 Java 字符串的子字符串是指原始字符串.

A big one is that getting substrings of Java strings refers to the original string.

示例:您读入 3000 个字符的记录并获得 12 个字符的子字符串,将其返回给调用者(在同一个 JVM 中).即使您没有直接引用原始字符串,该 12 个字符的字符串仍在内存中使用 3000 个字符.

Example: you read in a 3000 character record and get a substring of 12 characters, returning that to the caller (within the same JVM). Even though you don't directly have a reference to the original string, that 12 character string is still using 3000 characters in memory.

对于接收并解析大量消息的系统来说,这可能是一个真正的问题.

For systems that receive and then parse lots of messages, this can be a real problem.

您有几种方法可以避免这种情况:

You have a couple of ways to avoid this:

String sub = new String(str.substring(6,12));

String sub = str.substring(6,12).intern();

第一个更明确.第二个具有其他含义,因为您正在使用 PermGen 空间.过度使用你可能会耗尽,除非你给你的虚拟机足够.

The first is more clearcut. The second has other implications because you're using PermGen space. Overused you could run out unless you give your VM enough.

请记住,这仅在您取小子字符串然后丢弃原始字符串并且您经常这样做时才相关.

Remember this is only relevant if you're taking small substrings and then throwing away the original string and you're doing this a lot.

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

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