Jvm陷阱
neek2000
2002.10.6
=========================================================================
前一段时间看见有人问关于JVM内存不足,异常退出的问题,今天看书中忽然想到,就写下来,和大家一起探讨一下。
很多时候一个Web程序(包括J2EE或是其他的应用),我们高高兴兴的写完,
自己觉得完全没有问题,但是一旦拿到实际的环境中一运行,问题就出现了:JVM
内存不足,然后异常退出。是程序内存泄漏吗?JVM不是有自动的垃圾回收嘛?
为什么不起作用呢?我们想尽一切办法,测试,解释,修改JVM启动参数,还是
没有效果,为什么呢?这个时候,我们就掉进了Java的虚拟机陷阱!
接下来我们就以JDBC为例子,来分析一下这个问题:
假设一个Web应用使用了ConnectionPool来管理数据库连接,开发、测试的
过程都没有问题,我们部署的时候根据目标机器的配置,内存的大小,精心计算
了JVM的堆栈大小,精心调节内存回收的时间,得出结论,我们这个Web应用的连接
池的大小是100个连接,并以此为结论,对整个系统进行设置。(假设数据库和Web
应用在一台机器上)
但是事实并不是这样,当我们的程序运行到一半的时候,JVM开到28个数据库
连接的时候,JVM告诉你,没有内存了!怎么回事?是内存泄漏吗?
我可以告诉你,不是!因为你掉进了JVM陷阱,你只看到的了JVM的内存管理
空间!
实际上在你的机器上的所有的物理内存空间里,只有很小的一部分是分配给你
的JVM的。还有很大的部分是分配给了数据库,和操作系统。一个JDBC的数据库连接
实际上包括三部分:
1. JVM可见的数据库连接部分内存。
2. 数据库引擎使用的内存部分。
3. 操作系统使用的通讯支持部分内存。
当我们建立的28个数据库连接的时候,JVM中的部分确实没有超出预算。但是这三
部分中的2和3占了大部分,而你的物理内存是有限的,这个时候你的JVM以外的内存
已经被瓜分完了,JVM自然申请不到内存,那不退出还等什么?:)
由此看来,我们在构建一个Web应用的时候,更多的要从整体考虑问题,不要被
JVM蒙蔽了眼睛,掉进“JVM的陷阱”!