Java游戏服务器占用太多内存!

Java游戏服务器占用太多内存!,java,java-server,Java,Java Server,我有一个基于Java的命令行服务器,运行着我在网站上制作的游戏的高分。它工作效率高,速度快。但是,它占用了大约200MB的RAM!我尝试了所有方法,从手动清除所有内容到调用System.gc() 我开始怀疑这可能与我从套接字连接使用的输入流和输出流对象有关。我注意到,当我第一次运行程序时,它占用了正常数量的RAM。然后,一旦获得连接,它就会跳到100MB,并且每次连接都会不断增加。 编辑:在我的一个类中,我在3个不同的数组列表中保存所有的名称、分数和时间戳。然而,使用jhat和jmap进

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

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

编辑:在我的一个类中,我在3个不同的数组列表中保存所有的名称、分数和时间戳。然而,使用jhat和jmap进行的彻底检查表明,它们结合起来只使用大约5MB的RAM。


如果这一点太模糊,任何人都无法回答,请提问,我将很乐意提供源代码。

您可能会因为在对象的使用寿命之外保留对对象的引用而导致泄漏

我建议你找一个剖析器,用它来调查。使用Java6发布的VisualVM程序是一个好的、免费的起点

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


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

尝试使用类似jmap的东西,然后使用jhat来查看内存的实际使用情况


Sun(Oracle)的JVM从不将内存释放回操作系统,因此内存使用率单调增加也就不足为奇了。

如果您看到每次连接内存都在上升,而客户端断开连接时内存没有下降,那么您很可能是在维护对封闭套接字的引用。如果JVM与.NET类似,那么“强制”垃圾收集不能保证实际收集任何东西,即使有未使用的对象没有对它们的引用。另外,如果你能以300美元的价格购买24GB内存,那么2亿只不过是小菜一碟。这真的是一个问题吗?@ide每次连接都会上升很多,然后随着连接断开而下降一些,因为我试图在对象生命结束之前手动清空所有对象的每个引用。@Merlyn Morgan Graham我在笔记本电脑上的命令提示符下运行此服务器,而不是在专用服务器上运行(我希望我有一台!)@Roi:嗯,如果确定要清空对每个套接字的所有引用,那么可能需要使用
-Xmx128m
运行JVM,以对GC施加一些压力。可能是某个地方的数据结构仍然保留着套接字引用,不过。。。jmap直方图选项产生了正常结果,表示总共使用了大约25MB的内存和近500000个实例。jmap dump和jhat也显示了正常的结果。@Roi,我想说这是你没有真正问题的证据,这取决于你是否期望那50万个对象存在。(你知道吗?如果没有,请在jhat中沿着参照图往上走。)顺便问一下,你是如何判断内存使用情况的?您是在查看分配给java的虚拟内存的大小,还是查看其驻留集的大小?第二段不正确。Oracle JVM确实会将内存释放回操作系统。。。“不情愿地”。查看
-XX:MaxHeapFreeRatio
选项。哦,是的,我以前使用过探查器,我只是不知道它被称为so:P,但是,我从来没有使用过VisualVM,所以我将对它进行一段时间的调查。非常感谢。看起来所有的名字和高分数据都占用了150MB,其余的都是JVM需要的。这是很多高分数据——我怀疑那里有些东西真的不正常。我知道!我只提交了大约130000个高分,存储它们的文件只有3MB。为了提高效率,当服务器第一次开始运行时,我读取文件并将所有名称和分数存储在ArrayList中。我无法理解为什么需要150MB。