|
32
|
| Stu Thompson Helter Scelter · 技术社区 · 16 年前 |
|
|
1
18
只是一个想法:NIO缓冲区放在JVM之外。 Why does the Sun JVM continue to consume ever more RSS memory even when the heap, etc sizes are stable? ]因为早在2009年,RHEL4就有glibc<2.10 (~2.3)
|
|
|
2
14
RSS表示正在使用的页面——对于Java,它主要是堆中的活动对象,以及JVM中的内部数据结构。除了使用较少的对象或进行较少的处理外,您无法做很多事情来减小其大小。
那么,在您的系统中还发生了什么?是不是有很多Tomcat服务器,每台服务器消耗300万RSS?您加入了很多GC标志,它们是否表示进程的大部分时间都在GC中?您是否在同一台计算机上运行数据库? 根据评论进行编辑
这让我怀疑你的号码。因此,请运行以下操作以获取快照,而不是一段时间内的图形(用您正在使用的任何进程ID替换7429):
(由Stu编辑,以便我们能够根据上述ps信息请求生成结果:)
编辑以向后代解释这些数字 如上所述,RSS是驻留集大小:物理内存中的页面。SZ持有进程可写的页面数(提交费用);手册页将此值描述为“非常粗略”。VSZ保存进程的虚拟内存映射的大小:可写页面加共享页面。
详细说明为什么唯一的解决方案是减少对象
我注意到你提到有几百到几千个线程。这些线程的堆栈也将添加到RSS中,尽管它应该不会太多。假设线程具有较浅的调用深度(典型的应用服务器处理程序线程),每个线程应该只消耗一两页物理内存,即使每个线程的提交费用为半兆。 |
|
|
3
3
JVM使用的内存不仅仅是堆。例如,Java方法、线程堆栈和本机句柄在内存中与堆以及JVM内部数据结构分开分配。
关于JNI,您写道应用程序没有使用JNI,但是。。。您使用的是哪种类型的JDBC驱动程序?它可能是2型的,并且有泄漏吗?这是非常不可能的,尽管正如您所说的,数据库使用率很低。 关于创建过多的线程,每个线程都有自己的堆栈,可能非常大。堆栈大小实际上取决于虚拟机、操作系统和体系结构,例如 JRockit 在Linuxx64上是256K,我在Sun的文档中没有找到Sun VM的参考资料。这直接影响线程内存(线程内存=线程堆栈大小*线程数)。如果创建和销毁大量线程,内存可能无法重用。
老实说,成百上千的线程对我来说似乎是巨大的。也就是说,如果您确实需要那么多线程,那么可以通过
|
|
|
4
1
众所周知,Java中当前的垃圾收集器不会释放分配的内存,尽管不再需要内存。然而,非常奇怪的是,您的RSS大小增加到>3GB,尽管堆大小限制为640MB。您是在应用程序中使用任何本机代码,还是启用了Tomcat本机性能优化包?在这种情况下,您的代码或Tomcat中当然可能存在本机内存泄漏。
|