1

我有一个基于 Java 的命令行服务器正在运行,它托管我在我的网站上制作的游戏的高分。它工作高效且快速。但是,它占用了大约 200MB 的 RAM!我已经尝试了从手动清除所有内容到调用 System.gc() 的所有方法

我开始怀疑这可能与我从 Socket 连接使用的输入流和输出流对象有关。我注意到,当我第一次运行该程序时,它会占用正常数量的 RAM。然后,一旦它获得连接,它就会跳到 100MB 并为每个连接不断变大。

编辑:在我的一门课程中,我将所有名称、分数和时间戳保存在 3 个不同的 ArrayList 中。但是,使用 jhat 和 jmap 进行的彻底检查表明,它们结合起来只使用了大约 5MB 的 RAM。

如果这对任何人来说都太模糊了,请询问,我很乐意提供源代码。

4

2 回答 2

3

您可能会因为保留对超出其使用寿命的对象的引用而导致泄漏。

我建议你找一个分析器并用它来调查。随 Java 6 一起发布的 VisualVM 程序是一个很好且免费的起点。

探查器是一个单独的程序,它附加到 JVM 或为您的程序托管一个 JVM 并监视程序的执行。它可以统计地或通过“检测”正在执行的代码来跟踪对象分配和代码执行。它将显示对象是否正在分配和未释放,并且可以显示它们是什么对象以及它们被分配的位置(以及许多其他有用的东西)。

我使用 jProfiler,它是商业的(但对于专业人士来说非常值得)。上次我搜索时,有几个免费的优质分析器(至少供个人使用)。VisualVM 具有基本但有用的分析功能,我将从那里开始(在 Windows 上,您可以在 JDK bin 目录中找到它;我认为 Linux 和 Mac 也是如此)。

于 2011-02-05T04:15:43.773 回答
0

尝试使用 jmap 之类的东西,然后使用 jhat 来查看您的内存实际是如何使用的。

Sun (Oracle) 的 JVM 永远不会将内存释放回操作系统,因此您看到内存使用量单调增加也就不足为奇了。

于 2011-02-05T04:55:17.877 回答