Java会耗尽内存,即使我付出了很多! [英] Java runs out of memory, even though I give it plenty!

查看:124
本文介绍了Java会耗尽内存,即使我付出了很多!的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我正在运行Java服务器(特别是Winstone: http://winstone.sourceforge.net/)

So, I'm running a java server (specifically 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

Like this: java -server -Xmx12288M -jar /usr/share/java/winstone-0.9.10.jar --useSavedSessions=false --webappsDir=/var/servlets --commonLibFolder=/usr/share/java

过去这种方法运行良好,但现在它需要将比以前更多的内容加载到内存中.

This has worked fine in the past, but now it needs to load a bunch more stuff into memory than it has before.

奇怪的是,根据"top",它具有15.0g的VIRT(双内存),而RES(标识集)为8.4g.一旦达到8.4g,CPU就会以100%的速度挂起(即使它是从磁盘加载的),最终,我得到了Java的OutOfMemoryError.大概CPU挂在100%的CPU是Java在做垃圾回收.

The odd part is that, according to 'top', it has 15.0g of VIRT(ual memory) and it's RES(ident set) is 8.4g. Once it hits 8.4g, the CPU hangs at 100% (even though it's loading from disk), and eventually, I get Java's OutOfMemoryError. Presumably, the CPU hanging at 100% is Java doing garbage collection.

所以,我的问题是,有什么用呢?我给了它12个演出的记忆!而且它只用了8.2场演出就可以了.我在做什么错了?

So, my question is, what gives? I gave it 12 gigs of memory! And it's only using 8.2 gigs before it throws in the towel. What am I doing wrong?

哦,我在用 Java版本"1.6.0_07" Java(TM)SE运行时环境(内部版本1.6.0_07-b06) Java HotSpot(TM)64位服务器VM(内部版本10.0-b23,混合模式)

Oh, and I'm using java version "1.6.0_07" Java(TM) SE Runtime Environment (build 1.6.0_07-b06) Java HotSpot(TM) 64-Bit Server VM (build 10.0-b23, mixed mode)

在Linux上.

谢谢, 马特

推荐答案

奇怪的是,根据"top",它具有15.0g的VIRT(双内存),而RES(标识集)为8.4g.一旦达到8.4g,CPU就会以100%的速度挂起(即使它是从磁盘加载的),最终,我得到了Java的OutOfMemoryError.

The odd part is that, according to 'top', it has 15.0g of VIRT(ual memory) and it's RES(ident set) is 8.4g. Once it hits 8.4g, the CPU hangs at 100% (even though it's loading from disk), and eventually, I get Java's OutOfMemoryError.

我认为您是在误解事物. "-Xmx12288M"选项不保留物理内存.相反,它为Java堆的大小设置了上限. Java还需要为非堆对象提供内存.例如permgen空间,代码空间,内存映射文件等. 一个12g的堆+ JVM使用/共享的非堆内存加起来达到15g是很合理的.

I think you are misinterpreting things. The "-Xmx12288M" option does not reserve physical memory. Rather it sets an upper limit on the size of the Java heap. Java also needs memory for non-heap objects; e.g. permgen space, code space, memory mapped files, etcetera. It is quite plausible for a 12g heap + the non-heap memory used/shared by the JVM to add up to 15g.

top报告为RES的8.4g是当前用于运行JVM的物理内存量.它与Java堆的大小没有直接关系.确实,您会期望RES编号随着OS虚拟内存系统交换不同进程的页面而上下移动.这完全超出了JVM的控制范围.

The 8.4g reported by top as RES is the amount of physical memory that is currently being used to run the JVM. It is not directly related to the size of your Java heap. Indeed, you would expect the RES number to move up and down as different processes' pages are swapped in and out by the OS virtual memory system. This is entirely outside the control of the JVM.

大概是100%挂起的CPU是Java进行垃圾回收.

Presumably, the CPU hanging at 100% is Java doing garbage collection.

是的.通常就是这样.

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

I can think of three possible explanations:

  • 很有可能,由于交换磁盘空间不足,操作系统无法将所需的内存提供给JVM.例如,如果您有2个进程,每个进程具有15g的虚拟内存,则为30gb.假设您有24g的物理内存,则至少需要8g(可能更多)的交换空间.如果可分配给用户进程的物理内存量+交换空间量小于进程所使用的虚拟空间总量,则OS将开始拒绝JVM扩展堆的请求.您可以运行"swapon -s"以查看有多少可用/正在使用的交换空间.

  • Most likely, the operating system is unable to give your JVM the memory it is asking for because there is not enough swap disk space. For example if you have 2 processes with 15g of virtual memory each, that's 30gb. Given that you have 24g of physical memory, you will need at least 8g (probably more) of swap space. If the amount of physical memory allocatable to user processes + the amount of swap space is less than the total virtual space used by processes the OS will start refusing requests by the JVM to expand the heap. You can run "swapon -s" to see how much swap space is available / in use.

您的应用程序可能确实正在使用您说过可以使用的全部12g堆,但这还不够. (也许您有存储泄漏.也许它确实需要更多的内存.)

Your application may really be using all of the 12g of heap that you've said it can use, and that is not enough. (Maybe you've got a storage leak. Maybe it really needs more memory.)

也可能(但极不可能)有人设置了流程限制.您可以使用shell内置的'ulimit'命令来查看是否已经完成;有关详细信息,请参阅"man ulimit".

It is also possible (but highly unlikely) that someone has set a process limit. You can use the shell builtin 'ulimit' command to see if this has been done; refer to "man ulimit" for details.

编辑

  • 如果使用-verbose:gc-XX:+PrintGCDetails选项,GC可能会为您提供有关正在发生的事情的更多线索.特别是,它将告诉您内存不足时Java堆的实际大小.

  • If you use the -verbose:gc and -XX:+PrintGCDetails options, the GC might give you more clues as to what is happening. In particular, it will tell you how big the Java heap really is when you run out of memory.

您可以编写一个小型Java应用程序,该应用程序仅分配内存并且不会释放大量内存,并在以与当前相同的选项运行时看到在发生OOM错误之前它可以分配多少内存使用. (我认为这不会告诉您任何新内容. EDIT 2 实际上,如果您按照@Dan建议的方式运行它,它会告诉您一些信息.)

You could write a little Java app that simply allocates and doesn't free lots of memory, and see how much it manages to allocate before falling over with an OOM error when run with the same options as you are currently using. (I don't think this will tell you anything new. EDIT 2 actually, it will tell you something if you run it in the way that @Dan suggests! )

如果(似乎很可能)真正的问题是您没有足够的交换空间,那么您无法在Java方面进行任何操作来解决此问题.您需要重新配置系统以具有更多的交换空间.请参阅Linux系统管理文档,有关swaponmkswap等的man页面.

If (as seems likely) the real problem is that you don't have enough swap space, there is nothing you can do on the Java side to fix this. You need to reconfigure your system to have more swap space. Refer to your Linux system administration documentation, the man pages for swapon, mkswap etcetera.

这篇关于Java会耗尽内存,即使我付出了很多!的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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