为什么tomcat实际使用内存会超过Xmx设置

系统:

jdk1.5.0_21 + tomcat-5.5.15

java配置项:
JAVA_OPTS='-Xms3096m -Xmx3096m -Dsun.net.inetaddr.ttl=180'

top:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

11021 work 15 0 5439m 4.5g 19m S 99.9 57.5 2002:16 /home/work/serversoft/jdk1.5.0_21/bin/java -Xms3096m -Xmx3096m -Dsun.ne

jmap 如下:
./jmap -heap 11021
Attaching to process ID 11021, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 1.5.0_21-b01

using thread-local object allocation.
Parallel GC with 4 thread(s)

Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 3246391296 (3096.0MB)
NewSize = 2686976 (2.5625MB)
MaxNewSize = -65536 (-0.0625MB)
OldSize = 1835008 (1.75MB)
NewRatio = 2
SurvivorRatio = 8
PermSize = 21757952 (20.75MB)
MaxPermSize = 88080384 (84.0MB)

Heap Usage:
PS Young Generation
Eden Space:
capacity = 849674240 (810.3125MB)
used = 484249472 (461.8162841796875MB)
free = 365424768 (348.4962158203125MB)
56.992368275163905% used
From Space:
capacity = 2097152 (2.0MB)
used = 2097152 (2.0MB)
free = 0 (0.0MB)
100.0% used
To Space:
capacity = 5636096 (5.375MB)
used = 0 (0.0MB)
free = 5636096 (5.375MB)
0.0% used
PS Old Generation
capacity = 2164260864 (2064.0MB)
used = 1473276648 (1405.0261001586914MB)
free = 690984216 (658.9738998413086MB)
68.07296996892885% used
PS Perm Generation
capacity = 80281600 (76.5625MB)
used = 45063680 (42.97607421875MB)
free = 35217920 (33.58642578125MB)
56.13201530612245% used

为什么RES(4.5g) > Xmx(3G)? 是否存在内存泄漏? 我的程序中使用了JNI。
另外:我只设置了Xms 和 Xmx 是不是不起作用啊?
大家给点建议,谢谢

首先要搞清楚JVM的内存机制:

JVM的内存分为两部分,本地内存+Heap内存

首先JVM本身是一个应用程序,一般是通过C、C++实现的,这个应用程序要正常运行,是一定要向操作系统申请内存的,维持这个进程正常运行的内存,即可以理解成本地内存。

其次,Java程序在运行过程中,会new出很多对象,这些对象又是保存在JVM的堆内存中的,Java程序在执行过程中,会加载很多类,这些类也是保存在堆内存中。
JVM内存模型以及垃圾回收的介绍可以参见:
[url]http://hi.baidu.com/xuwanbest/blog/item/0587d82f2c44a73d1e30892e.html[/url]

JVM本身要对堆内存进行维护和管理,还负责垃圾回收,这些也同时会消耗本地内存,JVM在启动过程中,会依赖一些动态库,这同样也消耗本地内存。

JAVA_OPTS='-Xms3096m -Xmx3096m -Dsun.net.inetaddr.ttl=180' 这个只是用于设置堆内存的大小,而JVM运行过程中到底会向操作系统申请多少内存,这个是由JVM在运行过程中动态决定的,我们无法设置