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

Heapsize and other memory configuration of java on Tomcat 7 container of Red Hat

我正在使用 Red Hat tomcat7 容器(与 docker 集线器上的 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) 

我不知道该如何解释这些信息。 我考虑过增加堆大小。

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

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

尽管您的问题并没有像@Razvan 那样真正解决您的问题:

What is the meaning of pd product or product? [in PrintFlagsFinal]

这意味着该标志可用于 'product'(已发布)构建,而不是用于开发、QA、诊断或实验用途的构建。 'pd' 表示依赖于平台(Solaris vs Linux vs Windows 等)。

Is the max heapsize = the max memory consumption of java or of your application or of your whole tomcat? Because after some investigation I saw the container was using a lot more memory than 1892 MB (19839...) when it had the outofmemory issue.

运行 Java 进程将内存用于除堆之外的许多事情。如果在任何 OS 上安装了完整的 JDK,您可以在 Linux 上使用 /proc/$pid/mapsjmap(默认格式)看到它:

  • JVM 本身的代码,包括解释器和 JIT 编译器 HotSpot,以及各种库,加上通过 JNI 或 JNA 访问的任何 'native' 代码,以及 'native' 数据。一般来说,代码可能会与其他进程共享,但我不确定这在 docker 容器中是否仍然如此。

  • 'Metaspace'(在 Java 8 中,'PermGen' 在早期版本中)和 'CodeCache' 包含加载的 类 和 JITted 代码为他们

  • 线程堆栈; Tomcat 使用了相当多的线程,即使 Java 代码没有,JVM 也有一些内置线程,也许还有本机线程

  • 'direct' 如果使用 NIO 缓冲区(我认为 Tomcat 至少有时可以)

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

此外,我不确定 docker 内存测量是否包括进程本身之外的任何内容。您可以与 topps -F.

进行比较