Java耗尽内存,即使我给它足够的!

Java耗尽内存,即使我给它足够的!,第1张

概述Java耗尽内存,即使我给它足够的!

所以,我正在运行一个Java服务器(特别是Winstone: http : //winstone.sourceforge.net/ )

像这样:java -server -Xmx12288M -jar /usr/share/java/winstone-0.9.10.jar –useSavedSessions = false –webappsDir = / var / servlets –commonlibFolder = / usr / share / java

这在过去一直很好,但现在它需要加载更多的东西到内存比以前。

奇怪的是,按照“top”,它有15.0g VIRT(ual内存),RES(IDent set)是8.4g。 一旦它达到8.4g,cpu挂起100%(即使从磁盘加载),最终,我得到Java的OutOfMemoryError。 据推测,cpu挂在100%是Java做垃圾收集。

Java进程使用更多的RAM比分配?

GetProcessMemoryInfo PROCESS_MEMORY_COUNTERS_EX.PrivateUsage始终为0

如何找出在linux上GNU C ++剩余多less空闲内存?

OpenCL – 如果GPU内存大于系统RAM,会发生什么情况

每当调用malloc / free时输出到stderr

所以,我的问题是,是什么给了? 我给了它12回忆录! 它只用了8.2个演出,然后才扔下毛巾。 我究竟做错了什么?

噢,我正在使用Java版本“1.6.0_07”Java™SE运行时环境(版本1.6.0_07-b06)Java HotSpot™64位服务器虚拟机(版本10.0-b23,混合模式)

在linux上。

谢谢,Matt

linux上的虚拟内存大小

为什么使用numa_alloc_onnode()分配导致“页面不存在”?

内存映射文件是线程安全的

检查windows下Python程序的最大内存使用情况

logginglinux中所有可执行文件/进程的内存访问

奇怪的是,按照“top”,它有15.0g VIRT(ual内存),RES(IDent set)是8.4g。 一旦达到8.4g,cpu就会挂起100%(即使从磁盘加载),最终,我得到Java的OutOfMemoryError。

我认为你是在误解事物。 “-Xmx12288M”选项不保留物理内存。 相反,它设置了Java堆的大小上限。 Java也需要非堆对象的内存; 例如permgen空间,代码空间,内存映射文件等等。 对于12g堆+由JVM使用/共享的非堆内存加起来15g是相当合理的。

顶层报告为RES的8.4g是当前用于运行JVM的物理内存量。 它与Java堆的大小没有直接关系。 事实上,当 *** 作系统虚拟内存系统将不同进程的页面交换出来时,您会期望RES编号上下移动。 这完全在JVM的控制之外。

据推测,cpu挂在100%是Java做垃圾收集。

是。 这通常会发生。

我可以想到三种可能的解释:

很可能, *** 作系统无法为您的JVM提供所需的内存,因为没有足够的交换磁盘空间。 例如,如果你有两个进程每个15g的虚拟内存,这是30GB。 考虑到你有24g物理内存,你至少需要8g(可能更多)的交换空间。 如果可分配给用户进程的物理内存量+交换空间量小于进程使用的虚拟空间总量,则OS将开始拒绝JVM扩展堆的请求。 您可以运行“swapon -s”以查看有多少交换空间可用/正在使用。

你的应用程序可能真的在使用你所说的可以使用的12g堆,这是不够的。 (也许你有一个存储泄漏,也许它确实需要更多的内存。)

也有可能(但极不可能)有人设定了流程限制。 你可以使用shell内置的'ulimit'命令来查看是否已经完成了; 详情请参阅“man ulimit”。

编辑

如果使用-verbose:gc和-XX:+PrintGCDetails选项,则GC可能会为您提供更多线索。 特别是,它会告诉你,当你的内存不足时,Java堆真的有多大。

你可以编写一个简单的分配的Java应用程序,并且不会释放大量的内存,并且在使用与当前使用的选项相同的选项运行时,看到它在分配之前有多少分配,并且出现OOM错误。 (我不认为这会告诉你任何新的东西, 编辑2实际上,它会告诉你一些东西,如果你以@Dan的方式运行它)

如果(看起来很可能)真正的问题是你没有足够的交换空间,那么在Java方面你没有办法解决这个问题。 您需要重新配置您的系统以获得更多的交换空间。 请参阅您的linux系统管理文档, swapon , mkswap等的man页。

有时候,OutOfMemorError并不意味着对象堆已经用完了,而是别的东西。 是否有任何其他信息在错误堆栈?

尤其是,JVM需要一堆与堆空间分开的内存/地址空间。 在某个时候,给这个进程添加更多的对象会给这个其他池留下更少的空间 – 反过来让OOME更有可能使用更大的“-Xmx”设置!

内存映射文件可以吃掉很多的地址空间; 未能正确关闭文件可以留下这个空间分配,直到GC /定稿,发生在一个不可预知的时间。 此外,拥有更大堆的GC会导致GC /终止 – 这意味着这个本地地址空间可能会保留更长时间,所以再次说明:更大的堆可能意味着更多的OOME由于其他内存的耗尽。

您也可以使用相同值的“-xms”来强制所有堆地址空间在启动时立即被抓取 – 可能在更方便/可理解/可重复的阶段触发故障。

最后,即使没有内存请求失败,也有一个OOME被抛出的门槛 – 但是GC需要“太多”的时间,这意味着垃圾被创建的速度与收集的速度一样快,可能是在一个紧密的循环中。 对于少量保留数据而言,大量低效率的磁盘负载(大量垃圾创建)可能会导致此问题。 查看[GC开销限制]了解详细信息。

你能升级到最新版本的java(1.6.0_17)吗?

也许是一个愚蠢的问题,但是你确定你的交换分区在程序启动时至少有15GB可用空间吗?

而只是为了确认,这不是PermGen的空间用完吗?

奇怪的是,按照“top”,它有15.0g VIRT(ual内存),RES(IDent set)是8.4g。 一旦它达到8.4g,cpu挂起100%(即使从磁盘加载),最终,我得到Java的OutOfMemoryError。 据推测,cpu挂在100%是Java做垃圾收集。

我猜想,Java必须使用它决定(或被迫)为你的数据使用磁盘空间的内存。 现在下一次它必须收集垃圾它必须使用IO来做到这一点。 在磁盘上做垃圾回收确实是相当昂贵的。 而且因为垃圾收集器可能会一次又一次地跳入。 这可能是为什么你的cpu在100%…做垃圾收集永远。

正如斯蒂芬所说的–verbose :gc和-XX:+ PrintGCDetails会给出更多的提示。

但是,除此之外,也许它会支付投资于一次不加载所有文件的实现? 在你的记忆力下工作并不像一个成功的策略。

总结

以上是内存溢出为你收集整理的Java耗尽内存,即使我给它足够的!全部内容,希望文章能够帮你解决Java耗尽内存,即使我给它足够的!所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1155739.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-01
下一篇 2022-06-01

发表评论

登录后才能评论

评论列表(0条)

保存