java在Red Hat Tomcat 7容器上的堆大小和其他内存配置



我使用的是一个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乘积或乘积的含义是什么
  • 最大堆大小=java、应用程序或整个tomcat的最大内存消耗量吗?因为经过一些调查,我发现容器在出现outofmemory问题时使用的内存比1892MB(19839…)多得多

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

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

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

pd乘积或乘积的含义是什么?[打印标志最终]

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

最大堆大小=java、应用程序或整个tomcat的最大内存消耗量吗?因为经过一些调查,我发现这个容器使用的内存比1892MB(19839…)多得多,当时它有内存不足的问题。

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

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

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

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

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

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

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

最新更新