先說一下項目:項目是古老的spring項目,部署在tomcat下,jdk版本是1.8。
今天晚上,項目中的trans服務上線,從catalina.out觀察服務重啟log
信息: Stopping ProtocolHandler ["http-bio-8280"] 四月 1, 2021 8:36:09 下午 org.apache.coyote.AbstractProtocol stop 信息: Stopping ProtocolHandler ["ajp-bio-8209"] 四月 1, 2021 8:36:09 下午 org.apache.coyote.AbstractProtocol destroy 信息: Destroying ProtocolHandler ["http-bio-8280"] 四月 1, 2021 8:36:09 下午 org.apache.coyote.AbstractProtocol destroy 信息: Destroying ProtocolHandler ["ajp-bio-8209"] /www/epaysch/tomcat-trans-8280/bin/catalina.sh: 行 419: 15147 已殺死 "/usr/local/java/jre/bin/java" "-Dnop" -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Xms1024m -Xmx2048m -Xss1024K -XX:PermSize=512m -XX:MaxPermSize=2048 -Dfile.encoding=UTF8 -Dsun.jnu.encoding=UTF8 -Djdk.tls.ephemeralDHKeySize=2048 -Djava.endorsed.dirs="" -classpath "/www/epaysch/tomcat-trans-8280/bin/bootstrap.jar:/www/epaysch/tomcat-trans-8280/bin/tomcat-juli.jar" -Dcatalina.base="/www/epaysch/tomcat-trans-8280" -Dcatalina.home="/www/epaysch/tomcat-trans-8280" -Djava.io.tmpdir="/www/epaysch/tomcat-trans-8280/temp" org.apache.catalina.startup.Bootstrap start Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=512m; support was removed in 8.0 Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=2048; support was removed in 8.0
四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Server version: Apache Tomcat/7.0.90
四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Server built: Jul 2 2018 17:05:37 UTC 四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Server number: 7.0.90.0
四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: OS Name: Linux 四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: OS Version: 3.10.0-862.el7.x86_64 四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Architecture: amd64 四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Java Home: /usr/local/java/jre 四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: JVM Version: 1.8.0_191-b12 四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: JVM Vendor: Oracle Corporation 四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: CATALINA_BASE: /www/epaysch/tomcat-trans-8280
四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: CATALINA_HOME: /www/epaysch/tomcat-trans-8280
四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Command line argument: -Dnop 四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager 四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Command line argument: -Xms1024m 四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Command line argument: -Xmx2048m 四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Command line argument: -Xss1024K 四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Command line argument: -XX:PermSize=512m 四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Command line argument: -XX:MaxPermSize=2048
四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Command line argument: -Dfile.encoding=UTF8 四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Command line argument: -Dsun.jnu.encoding=UTF8 四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Command line argument: -Djava.endorsed.dirs=
四月 1, 2021 8:36:29 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Command line argument: -Dcatalina.base=/www/epaysch/tomcat-trans-8280
其中, /usr/local/java/jre/bin/java" "-Dnop" -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Xms1024m -Xmx2048m -Xss1024K -XX:PermSize=512m -XX:MaxPermSize=2048 -Dfile.encoding=UTF8 -Dsun.jnu.encoding=UTF8 -Djdk.tls.ephemeralDHKeySize=2048 -Djava.endorsed.dirs="" -classpath "/www/epaysch/tomcat-trans-8280/bin/bootstrap.jar:/www/epaysch/tomcat-trans-8280/bin/tomcat-juli.jar" -Dcatalina.base="/www/epaysch/tomcat-trans-8280" -Dcatalina.home="/www/epaysch/tomcat-trans-8280" -Djava.io.tmpdir="/www/epaysch/tomcat-trans-8280/temp" org.apache.catalina.startup.Bootstrap start 是啟動腳本。可以看到jvm堆內存參數設置是:-Xms1024m -Xmx2048m -Xss1024K -XX:PermSize=512m -XX:MaxPermSize=2048
緊接着可以看到HotSpot虛擬機的兩個提示:ignoring option PermSize / MaxPermSize; support was removed in 8.0,意思是,PermSize 、 MaxPermSize 這些參數在jdk1.8已經移除了。
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=512m; support was removed in 8.0 Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=2048; support was removed in 8.0
再看近期發版的服務重啟log,也有這個提示。
[viewlog@youfu-server tomcat-trans-8280]$ grep 'ignoring option PermSize' /www/epaysch/tomcat-trans-8280/logs/catalina.2021-03-2*.out
/www/epaysch/tomcat-trans-8280/logs/catalina.2021-03-23.out:Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=512m; support was removed in 8.0
ps一下tomcat的進程,從中可以看到有-XX:PermSize=512m -XX:MaxPermSize=2048參數
(這里分享個小技巧:我們使用viewlog賬號查看生產服務器的log,通常只有grep、ls這些命令,而沒有權限執行ps這些命令。 如下這種執行方式就是小竅門)
[viewlog@youfu-server bin]$ cd /usr/bin/ [viewlog@youfu-server bin]$ ./ps -ef |grep 'tomcat-trans' viewlog 3585 1391 0 12:09 pts/10 00:00:00 grep --color=auto tomcat-trans yfpay 30832 1 0 Apr08 ? 00:00:00 /bin/sh /www/epaysch/tomcat-trans-8280/bin/catalina.sh start yfpay 30833 1 0 Apr08 ? 00:02:07 /usr/local/sbin/cronolog /www/epaysch/tomcat-trans-8280/logs/catalina.%Y-%m-%d.out yfpay 30834 30832 1 Apr08 ? 01:23:05 /usr/local/java/jre/bin/java -Dnop -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Xms1024m -Xmx2048m -Xss1024K -XX:PermSize=512m -XX:MaxPermSize=2048 -Dfile.encoding=UTF8 -Dsun.jnu.encoding=UTF8 -Djdk.tls.ephemeralDHKeySize=2048 -Djava.endorsed.dirs= -classpath /www/epaysch/tomcat-trans-8280/bin/bootstrap.jar:/www/epaysch/tomcat-trans-8280/bin/tomcat-juli.jar -Dcatalina.base=/www/epaysch/tomcat-trans-8280 -Dcatalina.home=/www/epaysch/tomcat-trans-8280 -Djava.io.tmpdir=/www/epaysch/tomcat-trans-8280/temp org.apache.catalina.startup.Bootstrap start
查看tomcat/bin/catalina.sh,有如下jvm配置參數
JAVA_OPTS="-Xms1024m -Xmx2048m -Xss1024K -XX:PermSize=512m -XX:MaxPermSize=2048 -Dfile.encoding=UTF8 -Dsun.jnu.encoding=UTF8"
查看java版本,服務器jdk版本是1.8,即8.0
[root@youfu-server ~]# java -version java version "1.8.0_191" Java(TM) SE Runtime Environment (build 1.8.0_191-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)
查看java安裝目錄
[root@youfu-server ~]# whereis java java: /usr/local/java /usr/local/java/bin/java [root@youfu-server ~]# which java /usr/local/java/bin/java
經查,java8已經擯棄了Perm的配置,不能再配置Perm永久代參數。而是引入了一個新的概念Metaspace。
在java虛擬機內部,class文件中包括類的版本、字段、方法、接口等描述信息,還有運行時常量池,用於存放編譯器生成的各種字面量和符號引用。存放這些“永久”數據的區域叫做永久代(Permanent Generation,簡稱PermGen)。永久代是一片連續的堆空間。在JVM啟動時通過命令行指定參數-XX:MaxPermSize來設定永久代最大可分配的內存空間。一個明顯的問題是,PermGen的size很難調整,並且一旦這個值設置不當,當JVM加載的類信息容量超過了這個設定值后,應用將會報OOM錯誤(OutOfMemoryError)。
JAVA從JDK7的HotSpot虛擬機開始永久代的移除工作。永久代在JDK8中被完全的移除了。所以永久代的參數-XX:PermSize和-XX:MaxPermSize也被移除了。
在JDK8中,類的元數據信息(class metadata)不再存儲在連續的堆空間上,而是被存儲在叫做Metaspace的本地內存(native memory)中。
由於類的元數據可以在本地內存(native memory)之外分配,所以其最大可利用空間是整個系統內存的可用空間。這樣,我們程序猿將不再會遇到OOM錯誤。
那么,解決辦法就是修改java配置參數為:
JAVA_OPTS="-Xms1024m -Xmx2048m -Xss1024K -XX:MataspaceSize=512m -XX:MaxMetaspaceSize=2048 -Dfile.encoding=UTF8 -Dsun.jnu.encoding=UTF8"
參考Java PermGen 去哪里了? ,本文對JVM永久代以及JDK8 JVM里的Metaspace有全面的介紹。是一篇好文。