java 查询 内存耗尽,Java会耗尽内存,即使我付出了很多!

So, I'm running a java server (specifically Winstone: http://winstone.sourceforge.net/ )

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.

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.

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?

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)

on Linux.

Thanks,

Matt

解决方案

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.

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.

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.

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

Yes. That's typically what happens.

I can think of three possible explanations:

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.

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.)

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.

EDIT

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.

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! )

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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值