去年,当我将第一个Grails应用程序部署到生产环境时,我遇到了一些Grails问题和高内存使用问题。我的应用程序会执行大量的数据库选择,插入,删除和更新,并且每分钟执行大约10000个活动会话/用户。
对于开发,我用1024M HEAP做得很好。然而,当部署到生产内存使用增加很多。我在几分钟内得到了OutOfMemory异常。我做的第一件事是将HEAP大小增加到2048M,并且应用程序现在会运行一周,然后再次抛出OutOfMemoryError异常。我还使用了-XX:+ UseConcMarkSweepGC垃圾收集器。
我猜想有一些内存泄漏,但我无法弄清楚。所以我安装了 Java Melody plugin来监视内存使用情况。我还用JVisualVM找出可以吃掉所有内存的对象类型。
经过几天的监测,结果发现没有内存泄漏,但是有一段时间的内存使用率经历了高峰。目前平均内存使用量约为1200MB。我再次将HEAP增加到3072M,现在尖峰永远不会使用比可用的更多的HEAP,但尖峰可能使用高达2800MB的内存。
我的应用程序现在稳定,并且可以运行数月,没有任何问题。然而,内存使用率仍然很高,我已经在几个月里做了一些工作来改善这一点。有两件事真的有助于减少内存使用量。
第一个很容易,禁用休眠二级缓存。如果您的数据频繁更改,这被称为有用的。对我来说,这也稍微改善了整体表现。这可以在grails-app/conf目录来完成/ DataSource.conf
cache.use_second_level_cache=false
cache.use_query_cache=false
我做的第二件事是调整Searchable plugin。我开始返回一千个点击,现在最高点击数是一百个。
这两个调整减少了75%的峰值。我还做了很多与查询有关的小调整,特别是减少查询返回的数据量。 例如,我有一个名为Issue的域名类有20多个属性,但是在渲染到视图时我只需要一些属性。它可以将结果转换到地图是这样的:
Issue.executeQuery(
"select new map(i.id as id, i.title as title i.date as date) FROM Issue i"
)
调整这样可以提高查询时,内存使用情况和整体性能。希望能帮助到你。
您没有-Xms意外设置为较高值?如果没有其他事情一定要去。虽然Grails的内存要求相当高,但对于非常简单的应用程序,它的范围更多在128mb-256mb之间。 – Ruben 2011-05-25 06:17:50
只是想编造一下,我有同样的问题:当我启动我的Grails应用程序(少于十几个控制器和域类,脚手架),但然后做_absolutely nothing_但保持运行,jvisualvm显示_continuously_攀登堆使用率。注意:我甚至没有击中应用程序(没有请求),只是启动。 – 2011-11-09 02:59:03