【问题标题】:Grails application hogging too much memoryGrails 应用程序占用过多内存
【发布时间】:2011-02-01 21:20:44
【问题描述】:

Tomcat 5.5.x 和 6.0.x

Grails 1.6.x

Java 1.6.x

操作系统 CentOS 5.x(64 位)

内存为384M的VPS服务器

JAVA_OPTS : 尝试了很多组合 - 包括以下

导出 JAVA_OPTS='-Xms128M -Xmx512M -XX:MaxPermSize=1024m'

export JAVA_OPTS='-server -Xms128M -Xmx128M -XX:MaxPermSize=256M'

(根据http://www.grails.org/Deployment的建议)

我创建了一个空白的 Grails 应用程序,即简单地通过使用命令 grails create-app 然后对其进行 WAR 处理

我在 VPS 服务器上运行 Tomcat

当我只是启动Tomcat服务器,没有部署任何应用程序时,可用内存约为236M 并且使用的内存大约是156M

当我部署“空白”应用程序时,内存消耗飙升至 360M,最终 Tomcat 实例在占用所有空闲内存后立即被杀死

如您所见,我的应用程序尽可能轻巧。

不知道为什么内存消耗这么高。

我实际上是在对实际应用程序进行故障排除,但已将范围缩小到更易于分享和解释的场景。

更新 我在 Windows 上的本地 Tomcat 5.5.x 上测试了相同的“空白”应用程序,它运行良好

Java 进程的内存消耗从 32M 猛增到 107M。但它并没有崩溃,它仍然在可接受的范围内

所以继续寻找答案...我想知道我的 Linux 机器是否有问题。不知道是什么...

更新 2 另见http://www.grails.org/Grails+Test+On+Virtual+Server

这证实了我的信念,即我的简单空白应用程序应该在我的配置上运行。

【问题讨论】:

  • 与堆本身(Xms 和 Xmx)相比,您的 XX:MaxPermSize 似乎过高。你能把它减少到 256。这不能解决你的问题,它只是一个观察。
  • 我尝试了几种组合 - 请参阅更新的问题。谢谢!

标签: java web-applications tomcat grails


【解决方案1】:

试图在尽可能少的内存中运行长时间运行的基于 Java 的应用程序是一种错误的经济做法。垃圾收集器,因此如果应用程序有足够的常规堆内存,它的运行效率会更高。给应用程序太少的堆,它会花费太多时间进行垃圾收集。

(这可能看起来有点违反直觉,但相信我:效果在理论上是可以预测的,在实践中是可以观察到的。)

编辑

实际上,我建议采用以下方法:

  1. 首先运行 Tomcat + Grails,尽可能多地使用内存,这样你就有了可以运行的东西。 (将 permgen 大小设置为默认值...除非您有明确的证据表明 Tomcat + Grails 正在耗尽 permgen。)

  2. 运行该应用程序一段时间以使其达到稳定状态并确定其平均工作集是多少。您应该能够通过内存分析器或通过检查 GC 日志来确定这一点。

  3. 然后将 Java 堆大小设置为(例如)两倍测量的工作集大小或更多。 (这是我在上面试图提出的观点。)

实际上,您的问题还有另一个可能的原因。即使您告诉 Java 使用给定大小的堆,也可能 无法 这样做。当 JVM 向操作系统请求内存时,有几种情况操作系统会拒绝。

  • 如果您正在运行操作系统的机器(真实或虚拟)没有更多未分配的“真实”内存,并且操作系统的交换空间已完全分配,它将不得不拒绝更多内存的请求。

  • 每个进程的内存限制也有可能(尽管不太可能)有效。这将导致操作系统拒绝超出该限制的请求。

最后,请注意,Java 使用更多的虚拟内存,只需将堆栈、堆和 permgen 数相加即可。有可执行文件 + DLL 使用的内存,用于 I/O 缓冲区的内存,可能还有其他东西。

【讨论】:

  • 对不起。我不确定我是否完全跟随你。你对我应该改变什么有什么建议吗?
【解决方案2】:

384MB 非常小。我在 enjoyvps.net 上运行一个 512MB VPS 的小型 Grails 应用程序(不以任何方式附属,只是一个快乐的客户),它已经以不到 200MB 的速度运行了几个月。不过,我正在运行 32 位 Linux 和 JDK,如果您无论如何都无法访问太多内存,那么将所有内存浪费在 64 位指针中是没有意义的。

【讨论】:

  • 你的意思是 enjoyvps.com- 对吧?刚看了一眼。看起来很整洁!谢谢你的提示。顺便说一句,您同意我也应该能够在 384M 上运行空白 grails 应用程序 - 对吧?
  • Grails 有点占用内存,但我发现 1.2 有很大帮助,特别是因为它在构建战争时预编译了 GSP,因此运行时的 permgen 使用率下降了很多。但是所有这些 MetaClass 实例都使用了大量内存,但这就是 Groovy 和 Grails 动态特性的代价。但是,虽然它应该以 384MB 启动,但这并没有留下太多的工作空间。
  • 如果需要的话,我不介意为我的 VPS 添加更多内存,但我不相信我已经达到了最大容量。我的意思是我正在使用的测试应用程序 - 具有零 GSP 或域类!它与 Grails 应用程序一样简单。
【解决方案3】:

您可以尝试部署一个 tomcat 监控 webapp,例如psiprobe 看看内存在哪里使用?

【讨论】:

    猜你喜欢
    • 2017-09-01
    • 2013-01-10
    • 2011-09-20
    • 2019-06-04
    • 1970-01-01
    • 1970-01-01
    • 2014-05-30
    • 2016-11-09
    • 1970-01-01
    相关资源
    最近更新 更多