Red Hat的Tomcat 7容器上的java的Heapsize和其他内存配置

时间:2016-05-05 07:39:14

标签: java tomcat docker heap-memory

我正在使用Red Hat tomcat7容器(与docker hub上的tomcat7非常相似):

registry.access.redhat.com/jboss-webserver-3/webserver30-tomcat7-openshift:1.2-12

我已经部署了一些.wars但是在执行了很多过程之后我遇到了以下错误:

GC overhead limit exceeded
java.lang.OutOfMemoryError: GC overhead limit exceeded

所以我想调查最大堆大小和其他内存设置:

命令:

java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'
Output:
Picked up JAVA_TOOL_OPTIONS: -Duser.home=/home/jboss -Duser.name=jboss          
     intx CompilerThreadStackSize                   = 0                         
          {pd product}                                                          
    uintx ErgoHeapSizeLimit                         = 0                         
          {product}                                                             
    uintx HeapSizePerGCThread                       = 87241520                  
          {product}                                                             
    uintx InitialHeapSize                          = 125829120                 
          {product}                                                             
    uintx LargePageHeapSizeThreshold                = 134217728                 
          {product}                                                             
    uintx MaxHeapSize                               = 1983905792             
          {product}                                                             
     intx ThreadStackSize                           = 1024                      
          {pd product}                                                          
     intx VMThreadStackSize                         = 1024                      
          {pd product}                                                          
openjdk version "1.8.0_91"                                                      
OpenJDK Runtime Environment (build 1.8.0_91-b14)                                
OpenJDK 64-Bit Server VM (build 25.91-b14, mixed mode) 

我不知道如何解释这些信息。 我想增加堆积。

  • pd产品或产品的含义是什么?
  • max heapsize = java或您的应用程序或整个tomcat的最大内存消耗量?因为经过一些调查后我发现容器在outofmemory问题时使用了比1892 MB(19839 ...)更多的内存。

2 个答案:

答案 0 :(得分:2)

Tomcat应该为所有应用程序使用单个JVM。这确实使用了1892 MB(1983905792 B / 1024 2 ),这里的问题可能是:

  • 您有内存泄漏 - 您正在保留对正在使用的对象的引用,并且它们导致您的VM无法通过垃圾回收释放内存。解释得更好here。 尝试通过查看superlist
  • 的输出来弄清楚为什么会发生这种情况
  • 您的应用正常运行,确实需要更多堆内存。您可以通过设置jmap -histo <javaPID>
  • 来增加内存

答案 1 :(得分:0)

虽然你的问题并没有真正解决你的问题,但正如@Razvan所做的那样:

  

pd产品或产品的含义是什么? [在PrintFlagsFinal中]

这意味着该标志可用于&#39;产品&#39; (发布)构建而不是用于发育,QA,诊断或实验用途的构建。 &#39; PD&#39;意味着平台依赖(Solaris vs Linux vs Windows等)。

  

max heapsize = java或你的应用程序或整个tomcat的最大内存消耗量?因为经过一些调查后我发现容器使用的内存远远超过1892 MB(19839 ...),因为它有内存问题。

正在运行的Java进程使用内存来处理堆以外的许多事情。如果在任何操作系统上安装了完整的JDK,您可以在Linux上使用/proc/$pid/mapsjmap(默认格式)查看此内容:

  • JVM本身的代码,包括解释器和JIT编译器HotSpot,以及各种库,以及任何&#39; native&#39;通过JNI或JNA访问的代码,以及&#39; native&#39;数据。通常,代码可以与其他进程共享,但我不确定这是否在docker容器中仍然存在。

  • &#39;元空间&#39; (在Java 8中,&#39; PermGen&#39;在早期版本中)和&#39; CodeCache&#39;其中包含加载的类和JITted代码

  • 线程堆栈; Tomcat使用了很多线程,即使Java代码没有,JVM也有一些内置线程,也可能是本机线程

  • &#39;直接&#39;如果使用NIO缓冲区(我认为Tomcat至少有时可以)

但是只有堆中的对象被垃圾收集,因此其他区域与GC失败无关。

此外,我不确定泊坞内存测量是否包含超出过程本身的任何内容。您可以与topps -F进行比较。