2012-05-25 103 views
1

我有一个Java应用程序的问题。昨天,当我部署它进行测试时,我们注意到我们的机器开始交换,即使这不是一个真正的怪物应用程序,如果你知道我的意思。 无论如何,我检查了顶部的结果,并看到它吃了大约100MB的内存(RES在顶部)我试图分析内存,并检查是否有内存泄漏,但我找不到一个。有一个未完成的PreparedStatement,我修正了,但没有多大意义。 我试着设置最小和最大堆大小(有人说最小堆大小不是必需的),它没有任何区别。Java高内存使用率

这是怎样我现在运行它:

#!/bin/sh 

$JAVA_HOME/bin/java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9025 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -XX:MaxPermSize=40m -Xmx32M -cp ./jarName.jar uk.co.app.App app.properties 

这里是顶部结果:

PID USER  PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND                                           
16703 root  20 0 316m 109m 6048 S 0.0 20.8 0:14.80 java 

我不明白,我最大配置和PermSize最大堆事情大小,总和达72mb。这就足够了,应用程序运行良好。为什么它仍然在吃109mb的记忆和吃什么?这是一个37mb的差异,这是相当高的比例。 (34%)。 我不认为这是内存泄漏,因为最大堆大小已设置,并且没有内存不足错误或任何内容。

一个intertesting的事情可能是,我用VisualVM做了堆转储,然后用EclipseMAT检查它,它表示在类加载器中可能存在泄漏。 这就是它说:

的类加载器/组件 “sun.misc.Launcher $ AppClassLoader @ 0x87efa40” 占地9807664(64.90%)字节。内存是 积累的“短[] []”通过“”。关键词sun.misc.Launcher $ AppClassLoader加载@ 0x87efa40

一个实例,我不能让太多的这一点,但可能是有用的。

感谢您的帮助提前。

编辑

我发现这一个,也许有什么我可以做... Tomcat memory consumption is more than heap + permgen space

回答

1

你尝试使用JConsole的分析的应用程序http://docs.oracle.com/javase/1.5.0/docs/guide/management/jconsole.html 否则,你也可以使用JProfiler的审判版本来描述应用程序 http://www.ej-technologies.com/products/jprofiler/overview.html?gclid=CKbk1p-Ym7ACFQ176wodgzy4YA

但是,检查高内存使用情况的第一步应该是检查您是否是我们在你的应用程序中收集对象,如数组,地图,集合,列表等等。如果是,那么检查它们是否保留对象的引用(即使没有使用)?

+0

我做了分析,正如我写的,我不能发现任何问题。 –

+0

将建议尝试调整这些标志:-XX:MaxHeapFreeRatio和-XX:MinHeapFreeRatio。在http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html的“性能选项” – Saurabh

4

Java的内存包括

  • 的堆空间。
  • 烫发区空间
  • 线程堆栈区。
  • 共享库,包括JVM的共享库(将被共享)
  • 的直接内存大小。
  • 存储器映射文件大小(将被共享)

有可能是其他其是供内部使用。

鉴于37 MB的PC内存价值约20美分,我不会担心它太多。 ;)

+0

中查看更多详细信息如果每次我的计算机需要更多内存时我可以折腾20美分,我会是一个可怜的人...;) – brimborium

+0

我明白你的观点,我担心的一点是,运行这个应用程序的服务器有512 Mb的RAM,如果我运行这个应用程序,机器开始交换。因此,这37 MB的重要性在于,如果我能够减少它,它会对我有所帮助。 –

+0

增加内存需要多少成本?那也能帮助你。 –