Ole*_*liv 60 java monitoring garbage-collection memory-management
我们在Jboss上运行了一个j2ee应用程序,我们希望监视它的内存使用情况.目前我们使用以下代码
System.gc();
Runtime rt = Runtime.getRuntime();
long usedMB = (rt.totalMemory() - rt.freeMemory()) / 1024 / 1024;
logger.information(this, "memory usage" + usedMB);
Run Code Online (Sandbox Code Playgroud)
这段代码工作正常.这意味着它显示了与现实相对应的记忆曲线.当我们从DB创建一个大的xml文件时,曲线会上升,在提取完成后,它会下降.
一位顾问告诉我们,明确调用gc()是错误的,"让jvm决定何时运行gc".基本上他的论点与此处讨论的相同.但我还是不明白:
ami*_*efr 52
如果你想真正了解VM内存中发生的事情,你应该使用像VisualVM这样的好工具.这个软件是免费的,这是一个很好的方式来看看发生了什么.
使用显式gc()调用没有什么是"错误的".但是,请记住,当您调用gc()时,您"建议"垃圾收集器运行.无法保证它会在您运行该命令的确切时间运行.
Mr.*_* 安宇 28
有一些工具可以让您监控VM的内存使用情况.该VM可以公开使用JMX内存统计信息.您还可以打印GC统计信息以查看内存随时间的变化情况.
调用System.gc()可能会损害GC的性能,因为对象会过早地从新代移到旧代,弱引用会过早清除.这可能导致内存效率降低,GC时间延长,缓存命中率降低(对于使用弱refs的缓存).我同意你的顾问:System.gc()很糟糕.我会使用命令行开关禁用它.
Fel*_*lix 10
你可以看一下stagemonitor.它是一个开源的Java(Web)应用程序性能监视器.它捕获响应时间指标,JVM指标,请求详细信息(包括请求探查器捕获的调用堆栈)等.开销很低.
或者,您可以使用伟大的时间序列数据库石墨来存储数据点的长历史,您可以使用花哨的仪表板查看这些数据点.
例:
查看项目网站,查看截图,功能描述和文档.
注意:我是stagemonitor的开发者
通过Visual VM查看tomcat中发生的事情.
http://www.skill-guru.com/blog/2010/10/05/increasing-permgen-size-in-your-server/
看看JVM args:http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp#DebuggingOptions
XX:-PrintGC在垃圾收集中打印消息.管理.
-XX:-PrintGCDetails在垃圾收集中打印更多细节.管理.(在1.4.0中引入.)
-XX:-PrintGCTimeStamps打印垃圾回收时的时间戳.可管理(1.4.0中引入)
-XX:-PrintTenuringDistribution打印终身年龄信息.
虽然您不打算通过显式调用来破坏JVM,System.gc()
但它们可能没有您期望的效果.要真正理解JVM中的内存发生了什么,读取Brian Goetz所写的任何内容和所有内容.
在生产系统上显式运行System.gc()是一个糟糕的主意.如果内存达到任何大小,整个系统可以在完整GC运行时冻结.在一个千兆字节大小的服务器上,这很容易非常明显,这取决于如何配置jvm,它有多少空间等等 - 我已经看到超过30秒的暂停.
另一个问题是,通过显式调用GC你实际上并没有监视JVM如何运行GC,你实际上是在改变它 - 取决于你如何配置JVM,它会在适当的时候进行垃圾收集,并且通常会逐步进行(它不会在内存不足时运行完整的GC).你将要打印出来的内容与JVM独自完成的内容完全不同 - 一方面,你可能会看到更少的自动/增量GC,因为你将手动清除内存.
正如尼克霍尔特的帖子指出的那样,打印GC活动的选项已经作为JVM标志存在.
你可以有一个线程,只需要以合理的间隔打印出免费和可用的线程,这将显示实际的mem使用情况.
如果您喜欢从命令行执行此操作的好方法,请使用 jstat:
http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jstat.html
它以可配置的时间间隔提供原始信息,这对于记录和绘图目的非常有用。