Grails堆空间间歇溢出 [英] Grails Heap space overflowing intermittently

查看:122
本文介绍了Grails堆空间间歇溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



经过几分钟或几天的操作后,我们的测试服务器上的Grails应用程序失败。我无法在开发人员或本地进行复制。



这里的stacktrace模式示例将其中间的1000行剪掉(这将继续像这样倾倒直到我重新启动Tomcat ):

  at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
在grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
at net.sf.ehcache.constructs.web.filter.Filter.doFilter(Filter.java:86)
at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
at net.bull.javamelody.JdbcWrapper $ DelegatingInvocationHandler.invoke(JdbcWrapper.java:231)
at grails.plugin。 cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
导致:javax.servlet.ServletException:javax.servlet.ServletException:org.springframework.web.util.NestedServletException:处理程序处理失败;嵌套的异常是java.lang.OutOfMemoryError:在net.sf.ehcache.constructs.web.filter.Filter.logThrowable上的Java堆空间
(Filter.java:143)$ net $ f $ b $ net.sf.ehcache。 constructs.web.filter.Filter.doFilter(Filter.java:91)
at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
at net.bull.javamelody.JdbcWrapper $ DelegatingInvocationHandler.invoke(JdbcWrapper.java:231)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
......
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
at grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
at net.sf.ehcache.constructs.web.filter.Filter.doFilter(Filter.java:86)
引起通过:javax.servlet.ServletException:org.springframework .web.util.NestedServletException:处理程序处理失败;嵌套异常是java.lang.OutOfMemoryError:grails.plugin.cache.web.filter.AbstractFilter.logThrowable上的Java堆空间
(AbstractFilter.java:116)$ grails.plugin.cache.web上的
。 filter.AbstractFilter.doFilter(AbstractFilter.java:70)
at grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
at net.sf.ehcache.constructs.web。 filter.Filter.doFilter(Filter.java:86)
at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
at net.bull.javamelody.JdbcWrapper $ DelegatingInvocationHandler.invoke( JdbcWrapper.java:231)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter( AbstractFilter.java:63)
at grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
at net.sf.ehcache.constructs.web.filter.Filter .doFilter(Filter.java:86)

..................
at net.sf.ehcache.constructs.web。 filter.Filter.doFilter(Filter.java:86)
at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
at net.bull.javamelody.JdbcWrapper $ DelegatingInvocationHandler.invoke( JdbcWrapper.java:231)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter( AbstractFilter.java:63)
at grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
at net.sf.ehcache.constructs.web.filter.Filter.doFilter( Filter.java:86)
at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
at net.bull.javamelody.JdbcWrapper $ DelegatingInvocationHandler.invoke(JdbcWrapper.java:231)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
at grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
at net.sf.ehcache.constructs.web.filter.Filter.doFilter(Filter.java:86)
at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
at net.bull.javamelody.JdbcWrapper $ DelegatingInvocationHandler.invoke(JdbcWrapper.java:231)
在grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
在grails。 plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
at grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
at net.sf. ehcache.constructs.web.filter.Filter.doFilter(Filter.java:86)
at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
at net.bull.javamelody。 JdbcWrapper $ DelegatingInvocation Handler.invoke(JdbcWrapper.java:231)
在grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
在grails.plugin.cache.web.filter。 AbstractFilter.doFilter(AbstractFilter.java:63)
at grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
at net.sf.ehcache.constructs.web.filter。 Filter.doFilter(Filter.java:86)
at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
at net.bull.javamelody.JdbcWrapper $ DelegatingInvocationHandler.invoke(JdbcWrapper。 java:231)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter。 java:63)
at grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
at net.sf.ehcache.constructs.web.filter.Filter.doFilter (Filter.java:86)
at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
at net.bull.javamelody.JdbcWrapper $ DelegatingInvocationHandler.invoke(JdbcWrapper.java:231 )
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63 )
at grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
at net.sf.ehcache.constructs.web.filter.Filter.doFilter(Filter.java:86 )
at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
at net.bull.javamelody.JdbcWrapper $ DelegatingInvocationHandler.invoke(JdbcWrapper.java:231)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
在grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
引起通过:org.springfram ework.web.util.NestedServletException:处理程序处理失败;嵌套异常是java.lang.OutOfMemoryError:在grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter上的Java堆空间
(PageFragmentCachingFilter.java:195)$ grails.plugin.cache.web上的
。 filter.AbstractFilter.doFilter(AbstractFilter.java:63)
... 132 more
引起:java.lang.OutOfMemoryError:Java堆空间

这看起来可能是一个应用程序错误发生,errorHandler被调用,继续调用自己... kaboom!

环境


  • Grails:2.0.4

  • Tomcat :apache-tomcat-7.0.28
  • 操作系统:红帽企业Linux服务器版本5.8(Tikanga)


Java

  Java版本1.6.0_22
OpenJDK运行时环境(IcedTea6 1.10.8)(rhel-1.27.1.10.8.el5_8-x86_64)
OpenJDK 64位服务器虚拟机(构建20.0-b11,混合模式)

在Dev Java中是(这可能是我试图让SA在测试系统中改变的主要问题)

  java version1.6 .0_30
Java™SE运行时环境(build 1.6.0_30-b12)
Java HotSpot™64位服务器虚拟机(构建20.5-b03,混合模式)

服务器当前只有0-5个用户登录,但是这个时间在24小时内消失。



分配的堆空间为5g,通常使用<20%。



另外还有两件奇怪的事情发生在测试中,而不是在开发中:




  • 日志,最初几乎没有日志记录,但由于问题已将其打开为DEBUG并在50日推出RollingFile 100Meg文件。日志很好,记录应用程序特定的东西,直到堆栈吹,然后他们唯一的东西是堆栈,同样适用于tomcat日志记录。即使在第50个日志下线之前关闭服务器也是如此。所以我不知道是否有一些应用程序特定的不祥之处触发了这一点。

  • JavaMelody插件:图表上的标签不可读有点像我的3一岁的人写了他们。我相信所有的操作系​​统字体都已加载,但可能会指向Java版本。 strong>
    是有2个正在运行,已经运行了它们而没有问题

    $ DB $配置:
    有8个数据源到传统数据库,每个目前可能有点饿,例如:

      def connectionPropertiesMedium = [
    maxActive: 100,
    maxIdle:30,
    minIdle:5,
    initialSize:30,
    testOnBorrow:true,
    testWhileIdle:false,
    testOnReturn:false,
    validationQuery:SELECT 1,
    minEvictableIdleTimeMillis:600000,
    timeBetweenEvictionRunsMillis:600000,
    numTestsPerEvictionRun:3,
    maxWait:10000,
    defaultTransactionIsolation:java .sql.Connection.TRANSACTION_READ_UNCOMMITTED
    ]

    堆转储:
    跑步w ith -XX:+ HeapDumpOnOutOfMemoryError -XX:HeapDumpPath = heapdump.hprof
    使用VisualVM进行读取,这对我来说显得很少(对我来说)70%+是char []上面的堆栈轨迹。 Eclipse MAT不会加载它。



    JVM参数:
    $ b

      CATALINA_OPTS = -  server -XX:+ HeapDumpOnOutOfMemoryError -XX:HeapDumpPath = heapdump.hprof -XX:MaxPermSize = 1024m -XX:MaxNewSize = 256m -XX:NewSize = 256m -Xms768m -Xmx1024m -XX:SurvivorRatio = 128 -XX:MaxTenuringThreshold = 0 -XX:+ UseTLAB -XX:+ UseConcMarkSweepGC -XX:+ CMSClassUnloadingEnabled -XX:+ CMSIncrementalMode -XX:-UseGCOverheadLimit -XX:+ ExplicitGCInvokesConcurrent 

    压力测试:
    应用程序可以运行一些强烈的查询,这些查询会被点击几次到200个模拟JMeter用户没有问题...实际上数据库确实有点慢......)但是内存问题在许多运行中没有被复制。

    所以如果任何人都可以读到这里我有2条线索(打开更多):




    • Java版本 - 旨在让OpenJDK和标准版本

    • 导致infin的Grails设置中的某些内容在发生错误时进行迭代/递归处理。


      直到我找到能够在机器中使用这些鬼魂的质子包,应用程序不会上线。



      任何想法?



      干杯...



      Update#1

      安装了Java 1.7并删除了OpenJDK,这无疑解决了JavaMelody显示问题。现在它是一个等待游戏,看看这是否解决了主要问题。有趣的是,该网站似乎明显更快。

      解决方案

      如果用户多次重新提交登录表单(至j_spring_security_check),它会导致User.save()更新最后登录时间)在自定义UserDetailsS​​ervice中调用,Hibernate会话在后续每个用户的调用时关闭。


      $ b 将User.save()移动到AuthenticationEventListener.onApplicationEvent AuthenticationSuccessEvent事件),它工作正常。

      基本设置来自 Spring安全核心插件 - 事件,我的是:

      到你的配置添加: grails.plugin.springsecurity.useSecurityEventListener = true



      在resources.groovy中:

        import security.AuthenticationEventListener 
      ....
      authenticationEventListener(AuthenticationEventListener)

      AuthenticationEventListener.groovy:

        class AuthenticationEventListener实现ApplicationListener< AuthenticationSuccessEvent> {
      $ b $无效onApplicationEvent(AuthenticationSuccessEvent事件){
      if(event instanceof AuthenticationSuccessEvent){
      UserDetails userDetails =(UserDetails)event.getAuthentication()。getPrincipal()
      def httpSession = SecurityRequestHolder.request.session
      $ b $ if(!httpSession.loggedIn){
      httpSession.loggedIn = true
      synchronized(httpSession.loggedIn){
      httpSession。 timeZone = userDetails.timeZone
      User.withSession {session - >
      if(session.isOpen()){
      User user = User.findByUsername(userDetails.username,[fetch:[roles:'eager']])
      user.lastLoggedIn = new Date ()
      user.save(flush:true)
      }
      }
      }
      }
      }
      }
      }


      I have one of those joyous problems that is intermittent and hard to replicate.

      After either minutes or days of operation my grails app on our Test server fails. I cannot replicate on Dev or my local.

      The stacktrace pattern example here clipped off the middle as its 1000's lines (this will just keep going dumping like this until I restart Tomcat):

      at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
          at grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
          at net.sf.ehcache.constructs.web.filter.Filter.doFilter(Filter.java:86)
          at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
          at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:231)
          at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
      Caused by: javax.servlet.ServletException: javax.servlet.ServletException: org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.OutOfMemoryError: Java heap space
          at net.sf.ehcache.constructs.web.filter.Filter.logThrowable(Filter.java:143)
          at net.sf.ehcache.constructs.web.filter.Filter.doFilter(Filter.java:91)
          at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
          at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:231)
          at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
      ......
          at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
          at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
          at grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
          at net.sf.ehcache.constructs.web.filter.Filter.doFilter(Filter.java:86)
      Caused by: javax.servlet.ServletException: org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.OutOfMemoryError: Java heap space
          at grails.plugin.cache.web.filter.AbstractFilter.logThrowable(AbstractFilter.java:116)
          at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:70)
          at grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
          at net.sf.ehcache.constructs.web.filter.Filter.doFilter(Filter.java:86)
          at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
          at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:231)
          at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
          at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
          at grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
          at net.sf.ehcache.constructs.web.filter.Filter.doFilter(Filter.java:86)
      
      ..................
          at net.sf.ehcache.constructs.web.filter.Filter.doFilter(Filter.java:86)
          at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
          at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:231)
          at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
          at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
          at grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
          at net.sf.ehcache.constructs.web.filter.Filter.doFilter(Filter.java:86)
          at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
          at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:231)
          at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
          at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
          at grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
          at net.sf.ehcache.constructs.web.filter.Filter.doFilter(Filter.java:86)
          at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
          at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:231)
          at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
          at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
          at grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
          at net.sf.ehcache.constructs.web.filter.Filter.doFilter(Filter.java:86)
          at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
          at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:231)
          at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
          at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
          at grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
          at net.sf.ehcache.constructs.web.filter.Filter.doFilter(Filter.java:86)
          at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
          at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:231)
          at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
          at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
          at grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
          at net.sf.ehcache.constructs.web.filter.Filter.doFilter(Filter.java:86)
          at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
          at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:231)
          at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
          at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
          at grails.plugin.springcache.web.GrailsFragmentCachingFilter.doFilter(GrailsFragmentCachingFilter.groovy:66)
          at net.sf.ehcache.constructs.web.filter.Filter.doFilter(Filter.java:86)
          at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
          at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:231)
          at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
          at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
      Caused by: org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.OutOfMemoryError: Java heap space
          at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
          at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
          ... 132 more
      Caused by: java.lang.OutOfMemoryError: Java heap space
      

      This looks like possibly an application error occurs, errorHandler is invoked which keeps calling itself...kaboom!

      Environment:

      • Grails: 2.0.4
      • Tomcat: apache-tomcat-7.0.28
      • OS: Red Hat Enterprise Linux Server release 5.8 (Tikanga)

      Java:

      java version "1.6.0_22"
      OpenJDK Runtime Environment (IcedTea6 1.10.8) (rhel-1.27.1.10.8.el5_8-x86_64)
      OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode)
      

      In Dev Java is (and this could be the main issue which I am trying to get SA to change in Test system)

      java version "1.6.0_30"
      Java(TM) SE Runtime Environment (build 1.6.0_30-b12)
      Java HotSpot(TM) 64-Bit Server VM (build 20.5-b03, mixed mode)
      

      The server currently only has anywhere from 0-5 users logged on but this ebbs and flows over a 24 hour period.

      Heap space allocated is 5g and typically <20% is used.

      There are 2 other odd things occuring in Test and not in Dev:

      • Logs, with almost no logging originally but due to issue have opened it up to DEBUG and RollingFile 100Meg files rolling off at the 50th. Logs are fine, logging app specific stuff until the Stack blows and then the only thing in them is the stack, same goes for the tomcat logging. This even when I shutdown the server well before the 50th log gets rolled off. So I have no idea if there is some app specic hoodoo going on that triggers this.

      • JavaMelody plugin: The labels on the graphs are unreadable kinda like my 3 year old wrote them. I believe all the OS fonts are loaded but could point to the Java version.

      Schedulers: Yes there are 2 running, have run them without issue

      DB Config: There are 8 dataSources to legacy DB's, each currently may be set a bit hungry, by example:

      def connectionPropertiesMedium = [
              maxActive: 100,
              maxIdle: 30,
              minIdle: 5,
              initialSize: 30,
              testOnBorrow: true,
              testWhileIdle: false,
              testOnReturn: false,
              validationQuery: "SELECT 1",
              minEvictableIdleTimeMillis: 600000,
              timeBetweenEvictionRunsMillis: 600000,
              numTestsPerEvictionRun: 3,
              maxWait: 10000,
              defaultTransactionIsolation: java.sql.Connection.TRANSACTION_READ_UNCOMMITTED
      ]
      

      HeapDump: Running with -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heapdump.hprof Reading with VisualVM this reveals little (to me anyway) 70%+ is char[] full of the stacktraces above. Eclipse MAT wont load it.

      JVM args:

      CATALINA_OPTS="-server -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heapdump.hprof -XX:MaxPermSize=1024m -XX:MaxNewSize=256m -XX:NewSize=256m -Xms768m -Xmx1024m -XX:SurvivorRatio=128 -XX:MaxTenuringThreshold=0 -XX:+UseTLAB -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:+CMSIncrementalMode -XX:-UseGCOverheadLimit -XX:+ExplicitGCInvokesConcurrent
      

      Stress test: There are a couple of intense queries the app can run, these are hit a few times by up to 200 simulated JMeter users without issue...actually the DB did have a bit of go slow ;) But the memory issue was not replicated on many runs.

      So if anyone reads this far I have 2 leads (open to more):

      • Java version - aiming to get off OpenJDK and on to standard release
      • Something in my Grails setup that is causing infinite/recursive processing when an error occurs.

      Until I find the proton packs that nuke these ghosts-in-the-machine are this app wont go-live.

      Any ideas?

      Cheers...

      Update #1

      Installed Java 1.7 and removed OpenJDK, this certainly fixed the JavaMelody display issue. Now its a waiting game to see if this fixed the primary issue. Interestingly the site seems noticeably faster.

      解决方案

      If the user resubmits the login form multiple times (to j_spring_security_check) it was causing a User.save() (eg to update last login time) being called in custom UserDetailsService, Hibernate session was closed on the subsequent calls for each user.

      Moved the User.save() to AuthenticationEventListener.onApplicationEvent(AuthenticationSuccessEvent event) and it works fine.

      Basic setup for this is from the docs at Spring security core plugin - events , mine is like:

      To your config add: grails.plugin.springsecurity.useSecurityEventListener = true

      In resources.groovy:

      import security.AuthenticationEventListener
      ....
      authenticationEventListener(AuthenticationEventListener)
      

      AuthenticationEventListener.groovy:

      class AuthenticationEventListener implements ApplicationListener<AuthenticationSuccessEvent> {
      
          void onApplicationEvent(AuthenticationSuccessEvent event) {
              if (event instanceof AuthenticationSuccessEvent) {
                  UserDetails userDetails = (UserDetails) event.getAuthentication().getPrincipal()
                  def httpSession = SecurityRequestHolder.request.session
      
                  if (!httpSession.loggedIn) {
                      httpSession.loggedIn = true
                      synchronized (httpSession.loggedIn) {
                          httpSession.timeZone = userDetails.timeZone
                          User.withSession { session ->
                              if (session.isOpen()) {
                                  User user = User.findByUsername(userDetails.username, [fetch: [roles: 'eager']])
                                  user.lastLoggedIn = new Date()
                                  user.save(flush: true)
                              }
                          }
                      }
                  }
              }
          }
      }
      

      这篇关于Grails堆空间间歇溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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