Grails应用程序占用太多内存 [英] Grails application hogging too much memory

查看:190
本文介绍了Grails应用程序占用太多内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Tomcat 5.5.x和6.0.x

Grails 1.6.x

Java 1.6.x



CentOS 5.x(64bit)


内存为384M的VPS服务器

JAVA_OPTS:尝试了许多组合 - 包括以下内容:

export JAVA_OPTS =' - Xms128M -Xmx512M -XX:MaxPermSize = 1024m'



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



href =http://www.grails.org/Deployment =nofollow noreferrer> http://www.grails.org/Deployment )

我已经创建了一个空白的Grails应用程序,也就是简单地通过命令grails create-app,然后对其进行了处理。



我在VPS服务器上运行Tomcat



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

当我部署我的空白应用程序时,内存消耗将达到360M,最终将达到360M正如你所看到的,我的应用程序是一样轻的。



不知道为什么内存消耗是如此之高。



我实际上正在排除一个真正的应用程序故障,但已经缩小到这种情况这是更容易分享和解释。



更新
我在本地Tomcat 5.5.x上测试了相同的空白在Windows上,它工作的很好



Java过程的内存消耗从32 M到107 M。但它没有崩溃,并且仍然在可接受的范围内。所以寻求答案仍在继续......我不知道我的Linux机器有什么问题。不知道是什么......



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



它证实了我的信念,即我简单空白的应用程序应该可以在我的配置上工作。

尝试在最小的可能内存中运行基于Java的长期应用程序是一种虚假的经济。如果垃圾收集器具有大量的常规堆内存,垃圾收集器以及应用程序将运行得更加高效。给一个应用程序太少堆,它会花费太多时间垃圾收集。



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

编辑

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


  1. 首先使用运行Tomcat + Grails尽可能多地为内存分配内存,以便您拥有可运行的内容。 (将permgen大小设置为默认值,除非您有明确的证据表明Tomcat + Grails正在耗尽permgen。)


  2. 运行应用程序一段时间让它达到稳定状态并找出它的平均工作集。您应该能够从内存分析器中或通过检查GC日志记录中找出结果。

  3. 然后将Java堆大小设置为(比如说)两次测量的工作组尺寸或更多。 (这正是我上面想要说明的。)

实际上,您的问题还有另一个可能的原因。即使你告诉Java使用给定大小的堆,也可能是因为它不能来做到这一点。当JVM从操作系统请求内存时,有一些操作系统会拒绝的情况。


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


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




最后,请注意Java使用更多虚拟内存只需将堆栈,堆和permgen数字加在一起即可解释。有可执行文件使用的内存+ DLL,用于I / O缓冲区的内存以及其他可能的内容。


Tomcat 5.5.x and 6.0.x

Grails 1.6.x

Java 1.6.x

OS CentOS 5.x (64bit)

VPS Server with memory as 384M

JAVA_OPTS : tried many combinations- including the following

export JAVA_OPTS='-Xms128M -Xmx512M -XX:MaxPermSize=1024m'

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

(As advised by http://www.grails.org/Deployment)

I have created a blank Grails application i.e simply by giving the command grails create-app and then WARed it

I am running Tomcat on a VPS Server

When I simply start the Tomcat server, with no apps deployed, the free memory is about 236M and used memory is about 156M

When I deploy my "blank" application, the memory consumption spikes to 360M and finally the Tomcat instance is killed as soon as it takes up all free memory

As you have seen, my app is as light as it can be.

Not sure why the memory consumption is as high it is.

I am actually troubleshooting a real application, but have narrowed down to this scenario which is easier to share and explain.

UPDATE I tested the same "blank" application on my local Tomcat 5.5.x on Windows and it worked fine

The memory consumption of the Java process shot from 32 M to 107M. But it did not crash and it remained under acceptable limits

So the hunt for answer continues... I wonder if something is wrong about my Linux box. Not sure what though...

UPDATE 2 Also see this http://www.grails.org/Grails+Test+On+Virtual+Server

It confirms my belief that my simple-blank app should work on my configuration.

解决方案

It is a false economy to try to run a long running Java-based application in the minimal possible memory. The garbage collector, and hence the application will run much more efficiently if it has plenty of regular heap memory. Give an application too little heap and it will spend too much time garbage collecting.

(This may seem a bit counter-intuitive, but trust me: the effect is predictable in theory and observable in practice.)

EDIT

In practical terms, I'd suggest the following approach:

  1. Start by running Tomcat + Grails with as much memory as you can possibly give it so that you have something that runs. (Set the permgen size to the default ... unless you have clear evidence that Tomcat + Grails are exhausting permgen.)

  2. Run the app for a bit to get it to a steady state and figure out what its average working set is. You should be able to figure that out from a memory profiler, or by examining the GC logging.

  3. Then set the Java heap size to be (say) twice the measured working set size or more. (This is the point I was trying to make above.)

Actually, there is another possible cause for your problems. Even though you are telling Java to use heaps of a given size, it may be that it is unable to do this. When the JVM requests memory from the OS, there are a couple of situations where the OS will refuse.

  • If the machine (real or virtual) that you are running the OS does not have any more unallocated "real" memory, and the OS's swap space is fully allocated, it will have to refuse requests for more memory.

  • It is also possible (though unlikely) that per-process memory limits are in force. That would cause the OS to refuse requests beyond that limit.

Finally, note that Java uses more virtual memory that can be accounted for by simply adding the stack, heap and permgen numbers together. There is the memory used by the executable + DLLs, memory used for I/O buffers, and possibly other stuff.

这篇关于Grails应用程序占用太多内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆