一次Tomcat的JVM调优总结

场景:

用户反馈,某一模块,闲时正常,一道用户量稍微大点,就会出现卡顿的情况,代码层面已经优化过了N次,数据库也清理出了资源,用户希望快速改善这个问题,因此尝试从JVM的调优来改善。

JAVA内存模型

来源

Java内存管理-JVM内存模型以及JDK7和JDK8内存模型对比总结(三) - 阿飞云 - 博客园

JVM内存:年轻代,老年代,永久代(jdk1.8永久移除,由元空间取代)_LZ_玉米的博客-CSDN博客

Java虚拟机规范(Java SE 7版)

 运行时常量池变化

各个版本的变化

 java8内存模型

JVM8内存图

方法区

方法区在JVM中也是一个非常重要的区域,它与堆一样,是被线程共享的区域。在方法区中,存储了每个类的信息(包括类的名称、方法信息、字段信息)、静态变量、常量以及编译器编译后的代码等。方法区是堆的一个逻辑部分,为了区分Java堆,它还有一个别名Non-Heap(非堆)。相对而言,GC对于这个区域的收集是很少出现的。当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。

Java 7及之前版本,我们也习惯称方法区它为“永久代”(Permanent Generation),更确切来说,应该是“HotSpot使用永久代实现了方法区”!

Java8为什么要将永久代替换成Metaspace?

  • 1、字符串存在永久代中,容易出现性能问题和内存溢出。
  • 2、类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困 难,太小容易出现永久代溢出,太大则容易导致老年代溢出。
  • 3、永久代会为 GC 带来不必要的复杂度,并且回收效率偏低。
  • 4、Oracle 可能会将HotSpot 与 JRockit 合二为一。

Java堆

堆是jvm内存管理的最大的一块区域,此内存区域的唯一目的就是存放对象的实例,所有对象实例与数组都要在堆上分配内存。它也是垃圾收集器的主要管理区域。java对可以处于物理上不连续的空间,只要逻辑上是连续的即可。线程共享的区域。如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将抛出OutOfMemoryError异常。

为了支持垃圾收集,堆被分为三个部分:

  • 年轻代 : 常常又被划分为Eden区和Survivor(From Survivor To Survivor)区(Eden空间、From Survivor空间、To Survivor空间(空间分配比例是8:1:1

  • 老年代

  • 永久代 (jdk 8已移除永久代,取而代之的是另一块与堆不相连的本地内存——元空间)

JVM内存分代

JVM内存分代模型1

JVM内存分代模型2

在 Java 中,堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old)。新生代 ( Young ) 又被划分为三个区域:Eden、S0、S1。 这样划分的目的是为了使 JVM 能够更好的管理堆内存中的对象,包括内存的分配以及回收。

Java 中的堆也是 GC 收集垃圾的主要区域。GC 分为两种:Minor GC、Full GC ( 或称为 Major GC )。

这里写图片描述

 垃圾回收过程

来源

(转)Java垃圾回收基本过程 - hy_wx - 博客园

过程描述

1、首先,将任何新对象分配给eden空间。两个survivor空间都是空的。


2、当eden空间填满时,会触发轻微的垃圾收集。


3、引用的对象被移动到第一个survivor空间。清除eden空间时,将删除为引用的对象。


4、在下一次Minor GC中,Eden区也会做同样的操作。删除未被引用的对象,并将被引用的对象移动到Survivor区。然而,这里,他们被移动到了第二个Survivor区(S1)。此外,第一个Survivor区(S0)中,在上一次Minor GC幸存的对象,会增加年龄,并被移动到S1中。待所有幸存对象都被移动到S1后,S0和Eden区都会被清空。注意,Survivor区中有了不同年龄的对象。

5、在下一次Minor GC中,会重复同样的操作。不过,这一次Survivor区会交换。被引用的对象移动到S0.幸存的对象增加年龄。Eden区和S1被清空。
 

6、此幻灯片演示了promotion。在较小的GC之后,当老化的物体达到一定的年龄阈值(在该示例中为8)时,它们从年轻一代晋升到老一代。
 

7、随着较小的GC持续发生,物体将继续被推广到老一代空间。
 

8、所以这几乎涵盖了年轻一代的整个过程。最终,将主要对老一代进行GC,清理并最终压缩该空间。
 

一段形象的描述

  Jvm区域总体分两类,heap区和非heap区。heap区又分:Eden Space(伊甸园)、Survivor Space(幸存者区)、Tenured Gen(老年代-养老区)。 非heap区又分:Code Cache(代码缓存区)、Perm Gen(永久代)、Jvm Stack(java虚拟机栈)、Local Method Statck(本地方法栈)。

    HotSpot虚拟机GC算法采用分代收集算法:

1、一个人(对象)出来(new 出来)后会在Eden Space(伊甸园)无忧无虑的生活,直到GC到来打破了他们平静的生活。GC会逐一问清楚每个对象的情况,有没有钱(此对象的引用)啊,因为GC想赚钱呀,有钱的才可以敲诈嘛。然后富人就会进入Survivor Space(幸存者区),穷人的就直接kill掉。

2、并不是进入Survivor Space(幸存者区)后就保证人身是安全的,但至少可以活段时间。GC会定期(可以自定义)会对这些人进行敲诈,亿万富翁每次都给钱,GC很满意,就让其进入了Genured Gen(养老区)。万元户经不住几次敲诈就没钱了,GC看没有啥价值啦,就直接kill掉了。

3、进入到养老区的人基本就可以保证人身安全啦,但是亿万富豪有的也会挥霍成穷光蛋,只要钱没了,GC还是kill掉。

JVM常用参数

来源

JVM常用基础参数-栈内存Xss讲解_泷泷养的乔小胖-CSDN博客_jvm xss

-Xms                                       初始堆内存大小,默认物理内存64/1

                                                -Xms = -XX:InitialHeapSize

-Xmx                                        最大堆内存,默认物理内存4/1

                                                 -Xmx = -XX:MaxHeapSize

-Xss                                        栈内存大小

                                                 设置单个线程栈大小,一般默认512~1024kb。

                                                 单个线程栈大小跟操作系统和JDK版本都有关系

                                                 -Xss = -XX:ThreadStackSize

-Xmn                                        年轻代大小

-XX:MetaspaceSize                    元空间大小

                                     元空间本质跟永久代类似,都是对JVM规范中方法区的实现。

                                     不过元空间与永久代最大的区别在于:元空间并不在虚拟机中,而是使用本机内存。

                                     因此,元空间大小仅受本地内存限制。

-XX:MetaspaceSize                    初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值


-XX:MaxMetaspaceSize                 最大空间,默认是没有限制的


-XX:MinMetaspaceFreeRatio            在GC之后,最小的Metaspace剩余空间容量的百分比,减少为分配空间所导致的垃圾收集


-XX:MaxMetaspaceFreeRatio            在GC之后,最大的Metaspace剩余空间容量的百分比,减少为释放空间所导致的垃圾收集

-XX:+PrintGCDetails                  打印GC详细日志信息

-XX:SurvivorRatio                    幸存者比例设置

                                     2个Survivor区(From幸存区或To幸存区)和Eden区的比值

-XX:NewRatio                         新生代比例设置

                                      新生代(Eden + 2*S)与老年代(不包括永久区)的比值

-XX:MaxTenuringThreshold        进入老年代阈值设置

JVM监控分析

来源

dump分析工具_JVM实战:JVM常用监控工具_weixin_39757169的博客-CSDN博客

在线监控工具

JPS (打印Java进程信息)

 常用命令: jps -l

 Jstat (JVM统计信息)

使用场景 :用于查看各个功能和区域的统计信息(如:类加载、编译相关信息统计,各个内存区域GC概况和统计)

格式 : jstat 【选项】 【进程ID】 [间隔时间/毫秒 ] [查询次数]

常用指令:jstat -gc PID

查看即时内存使用情况、垃圾回收统计信息,用于分析GC情况。

 指令: jstat  -gc  16462  1000  5
 //查看16462进程 应用的堆内存使用、垃圾回收统计信息,每个1000毫秒输出一次,总共输入5次 。

 参数说明

 S0C 和 S0U    //S0区的总内存大小和已使用的内存大小。
 ​
 S1C: 和S1U   //S1区的总内存大小和已使用的内存大小。。
 ​
 EC 和 EU     //Eden区的总内存大小 和已使用的内存大小。
 ​
 OC和OU       //Old区的总内存大小 和已使用的内存大小。
 ​
 MC和MU       //方法区的总内存大小 和已使用的内存大小。
 ​
 CCSC和CCSU   //压缩类空间大小 和已使用的内存大小。
 ​
 YGC和 YGCT   //Young GC 的总次数 和消耗总时间。
 ​
 FGC和 FGCT   //Full Gc的总次数和消耗总时间。
 ​
 GCT         //所有GC的消耗时间。

 jvm耗时和频率计算

来源

java ygc 频繁_jvm之判断ygc耗时和频率_琥蛮的博客-CSDN博客

ygc平均耗时=YGCT/YGC(s)

ygc时间间隔=程序的运行时间/YGC

fgc平均耗时=FGCT/FGC(s)

fgc时间间隔=程序的运行时间/FGC

 程序运行总时间查看

ps -p {pid} -o etime

 总结

如果各项参数设置合理,系统没有超时日志出现,GC频率不高,GC耗时不高,那么没有必要进行GC优化;如果GC时间超过1?3 秒,或者频繁G C ,则必须优化。如果满足下面的指标,则一般不需要进行GC调整。

Jinfo(JVM参数查看修改)

使用场景: 查看和调整JVM启动和运行参数。

案例一:查看JVM整个系统参数信息

比如:输出16462进程jvm的全部参数和系统属性。

指令 : jinfo 16462

案列二: 查看某个具体参数

比如:查看老年代内存大小

指令:jinfo -flag OldSize 16462

案列三:启用某个配置

比如:开启堆内存溢出日志打印(默认是关闭的)。

指令:jinfo -flag +PrintGCDetails 16462

案例四:修改某个参数值

比如:修改当堆内存对象所占空间超过80%时进行扩容

指令:jinfo -flag MaxHeapFreeRatio=80 16462

案列五:启用某个配置

比如: 启动GC日志打印

指令:jinfo -flag +PrintGCDetails 16462

Jmap(JVM内存信息监控)

使用场景: 监控堆内存使用情况和对象占用情况, 生成堆内存快照文件,查看堆内存区域配置信息。注意生产环境中如果程序的堆占用内存已经很大的话,不建议用这个分析

格式:jmap 【选项】【进程ID】

案例一:查看堆内存的配置和使用情况

jmap -heap 18230 

 Heap Configuration:
    MinHeapFreeRatio         = 0             //JVM堆缩减空间比率,低于则进行内存缩减
    MaxHeapFreeRatio         = 100           //JVM堆扩大内存空闲比例,高于则进行内存扩张 
    MaxHeapSize              = 994050048 (948.0MB)   //堆最大内
    NewSize                  = 20971520 (20.0MB)     //新生代初始化内存大小
    MaxNewSize               = 331350016 (316.0MB)   //新生代最大内存大小
    OldSize                  = 41943040 (40.0MB)     //老年代内存大小
    NewRatio                 = 2                     //新生代和老年代占堆内存比率
    SurvivorRatio            = 8                      //s区和Eden区占新生代内存比率
    MetaspaceSize            = 21807104 (20.796875MB)  //元数据初始化空间大小
    CompressedClassSpaceSize = 1073741824 (1024.0MB)     //类指针压缩空间大小
    MaxMetaspaceSize         = 17592186044415 MB       //元数据最大内存代销      
    G1HeapRegionSize         = 0 (0.0MB)             //G1收集器Region单元大小
 ​
 Heap Usage:
 PS Young Generation
 Eden Space: 
    capacity = 303038464 (289.0MB)             //Eden区总容量
    used     = 22801000 (21.744728088378906MB)  //Eden区已使用荣浪
    free     = 280237464 (267.2552719116211MB)   //Eden区剩余容量
    7.524127366221075% used                      //Eden区使用比例
 From Space:      //From区(也就是Survivor中的S1区)                             
    capacity = 13107200 (12.5MB)                    //S1区总容量大小
    used     = 5364536 (5.116020202636719MB)          //S1区已使用大小
    free     = 7742664 (7.383979797363281MB)           //S1区剩余大小
    40.92816162109375% used                       //S1使用比例
 To Space:      //To区 (也就是Survivor中的S2区)      
    capacity = 13631488 (13.0MB)              //S2区总容量大小
    used     = 0 (0.0MB)                     //S2区已使用大小
    free     = 13631488 (13.0MB)             //S2区剩余大小
    0.0% used                                //S2区使用比率
 PS Old Generation           
    capacity = 110624768 (105.5MB)           //老年代总容量大小
    used     = 49431224 (47.14128875732422MB) //老年代已使用大小
    free     = 61193544 (58.35871124267578MB) //老年代剩余大小
    44.68368602589973% used                   //老年代使用功能比例
 ​ 

案例二:查看JVM中对应类型对象的数量、占用内存情况

统计实例最多的类 前十位有哪些

jmap -histo 18230 | sort -n -r -k 2 | head -10 

统计合计容量前十的类有哪些

jmap -histo 18230 | sort -n -r -k 3 | head -10 

案例三:dump 堆快照

命令:jmap -dump:live,format=b,file=/home/myheapdump.hprof 18230

 live   加上live代表只dump存活的对象 ;
 fomat  格式
 filie  导出的文件名
 18230  java进程ID

这里生成的 dump文件可以用我们后面讲的可视化工具VisualVM来打开文件对里面的内容进行分析。 

VisualVM分析dump文件

来源

用jvisualvm分析dump文件_huangpeigui的专栏-CSDN博客_jvisualvm分析dump文件

注意装入时候选择的文件类型

 VisualVM插件安装

来源

jvisualvm 无法下载插件解决方案_xixingzhe2的博客-CSDN博客

url地址:

https://visualvm.github.io/pluginscenters.html

选择对应版本的地址进入

 复制Catalog URL

 插件中心配置

将复制的地址拷贝到插件中心的地址中

第三方在线监控工具(Arthas)

Arthas 是Alibaba开源的Java诊断工具,它可以帮助我们解决在线环境的以下问题

  1. 监控到JVM的实时运行状态(涵盖Jps ,jstat ,jinfo ,jstack ,部分Jmap功能)。
  2. 在不需要重新部署服务的情况下修改业务代码。
  3. 以局视角来查看系统的运行状况。

JVM调优总结

GC大致流程

来源:

JVM GC调优一则--增大Eden Space提高性能_anningzhu的博客-CSDN博客

大部分新对象在Eden Space上分配,当Eden Space满了,则要用到Survivor Space来回收。YGC的算法是很快的

多次YGC之后,还存活的对象就会被移到Old Generation(old space)上,当Old Generation满了的时候,就会FGC,FGC有通常比较慢

Permanent Space只要你在开始时分配了足够大的空间,那它可以不用管

理想的GC/内存使用情况:

Old Space增长缓慢,FullGC次数少,FullGC的时间短(大部情况应该要在1秒内)。

总结:

尽量少加上一些默认参数。这点我很赞同RednaxelaFX的看法,配置了默认参数除了让后面调优的人蛋疼之外,没有太多的帮助。

GC调优就是一个取舍权衡的过程,有得必有失,最好可以在多个不同的实例里,配置不同的参数,然后进行比较。

尽可能最小化"短暂对象"移动到老年代的数量,同时最小化年轻代GC的次数和持续时间,要找到适当的折衷方案,首先要了解应用程序中对象年龄的分布情况。

有很多命令行工具或者图形工具可以使用,好的工具事半功倍。

调优总结:

1.新生代(Young generation)的空间太小,导致有一些本应该可以很快就被回收的对象被放到了老生代(Old generation)里,导致老生代上涨很快,频繁Full GC

2.内存泄露(Memory Leak):程序在申请内存后,对象没有被GC所回收,它始终占用内存,内存泄漏的堆积最终会造成内存溢出。

3.内存溢出(Memory Overflow):程序运行过程中无法申请到足够的内存而导致的一种错误。内存溢出通常发生于OLD段或Perm段垃圾回收后,仍然无内存空间容纳新的Java对象的情况。通常都是由于内存泄露导致堆栈内存不断增大,从而引发内存溢出。

4.如果Eden区域设置太大

新生成的对象会被分配在Eden区,Eden空间不足时会触发MinorGC。理想状态下,如果所有对象在这个阶段全部被回收,Eden区域被清空,不会出什么问题。如果GC后还存在一部分幸存的对象,则会被复制到To Survivor区域,此时因为Survivor区域空间太小无法容纳这些对象,结果大部分幸存对象只在进行一次或很少次的GC后就会被移动到老年代,也就是说从某种程度上来讲失去了MinorGC的初衷,这种情况是肯定不被允许的。

5.Eden区域设置太小

Eden区域设置太小,意味着其空间很快就会被占满,也就是说增加了新生代的GC次数,而频繁的GC会降低整体JVM性能。

6.年轻代大小选择

响应时间优先的应用:尽可能设大,直到接近系统的最低响应时间限制(根据实际情况选择)。在此种情况下,年轻代收集发生的频率也是最小的。同时,减少到达年老代的对象。
吞吐量优先的应用:尽可能的设置大,可能到达Gbit的程度。因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8CPU以上的应用。

7.年老代大小选择
响应时间优先的应用:年老代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数。如果堆设置小了,可以会造成内存碎片、高回收频率以及应用暂停而使用传统的标记清除方式;如果堆大了,则需要较长的收集时间。最优化的方案,一般需要参考以下数据获得:
并发垃圾收集信息
持久代并发收集次数
传统GC信息
花在年轻代和年老代回收上的时间比例
减少年轻代和年老代花费的时间,一般会提高应用的效率

吞吐量优先的应用:一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代。原因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而年老代尽存放长期存活对象。

8.较小堆引起的碎片问题
因为年老代的并发收集器使用标记、清除算法,所以不会对堆进行压缩。当收集器回收时,他会把相邻的空间进行合并,这样可以分配给较大的对象。但是,当堆空间 较小时,运行一段时间以后,就会出现“碎片”,如果并发收集器找不到足够的空间,那么并发收集器将会停止,然后使用传统的标记、清除方式进行回收。如果出 现“碎片”,可能需要进行如下配置:
-XX:+UseCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩。
-XX:CMSFullGCsBeforeCompaction=0:上面配置开启的情况下,这里设置多少次Full GC后,对年老代进行压缩。

来源:JVM调优总结 + jstat 分析【转】 - daddy再出发 - 博客园

 9 Full GC过多

出现full gc的原因多是慢处理和高并发
(1)内存分配不合理,导致对象频繁进入老年代,进而引发频繁的Full GC;
(2) 存在内存泄漏等问题,就是内存里驻留了大量的对象塞满了老年代,导致稍微有一些对象进入老年代就会引发Full GC;
(3) 永久代里的类太多,触发了Full GC

导出dump文件
jmap -dump:live,format=b,file=/home/server/heap.bin 55025
使用mat分析
https://www.eclipse.org/mat/downloads.php 

10. cpu过高
(1)一般是创建过多线程并发执行,且工作负载都很重,
(2) 频繁full gc

11.堆内存溢出

 原因:高并发,慢查询

12.永久代(元空间)内存溢出

原因:使用字节码技术生产了太多的类

13.OOM处理排查

我们可以让JVM在OOM时dump一份内存快照,事后我们只要分析这个内存快照,一下就可以知道是哪些可恶的对象占用了所有的内存,并且还无法释放。

-XX:+HeapDumpOnOutOfMemoryError 在OOM的时候自动dump内存快照出来
-XX:HeapDumpPath=/usr/local/app/oom 把内存快照放到哪儿去

 14.内存耗费过高

内存耗费超过50%感到有点惊讶,因为这说明他几乎快要把分配给他的内存消耗殆尽了!
1 在内存使用这么高的情况下会发生什么?

第一种:是内存使用率居高不下,导致频繁的进行full gc,gc带来的stop the world问题影响了服务。
第二种:是内存使用率过多,导致JVM自己发生OOM。
第三种:是内存使用率过高,也许有的时候会导致这个进程因为申请内存不足,直接被操作系统把这个进程给杀掉了!

15.常见内存溢出

(1) java.lang.OutOfMemoryError: Java heap space —-JVM Heap(堆)溢出

解决方法:手动设置 JVM Heap(堆)的大小。

(2) java.lang.OutOfMemoryError: PermGen space  —- PermGen space溢出。

解决方法: 手动设置 MaxPermSize 大小

(3) java.lang.StackOverflowError   —- 栈溢出

解决方法:修改程序。

(4)java.lang.StackOverflowError异常

解决方法:Java中,栈的大小通过-Xss来设置,当栈中存储数据比较多时,需要适当调大这个值

 来源

jvm日志分析_姚灿鹏的博客-CSDN博客

Tomcat的JVM调优

来源:

修改Tomcat使用的JVM内存大小_翻越山峰-CSDN博客_tomcat修改jvm内存大小

文件配置 

Linux下修改JVM内存大小:

要添加在tomcat 的bin 下catalina.sh 里,位置cygwin=false前 。注意引号要带上,红色的为新添加的.

# OS specific support. $var _must_ be set to either true or false.
JAVA_OPTS="-Xms256m -Xmx512m -Xss1024K -XX:PermSize=128m -XX:MaxPermSize=256m"
cygwin=false

windows下修改JVM内存大小:

情况一:解压版本的Tomcat, 要通过startup.bat启动tomcat才能加载配置

要添加在tomcat 的bin 下catalina.bat

rem Guess CATALINA_HOME if not defined
set CURRENT_DIR=%cd%后面添加,红色的为新添加的.

set JAVA_OPTS=-Xms256m -Xmx512m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m -Djava.awt.headless=true
 

推荐JVM优化参数

来源:

tomcat jvm参数优化 - Jasper_boy - 博客园

CATALINA_OPTS="
-Xms2g   #初始堆大小
-Xmx2g   #最大堆大小
-Xss512k #线程栈大小,出现java.lang.StackOverflowError时增大此值
-Xmn1000m #年轻代大小,对半分
-XX:MetaspaceSize=128m  #元数据类存储空间大小,存储与系统内存
-XX:MaxMetaspaceSize=512m  #最大元数据类存储空间大小
-Xloggc:/usr/local/tomcat/logs/gc.log #记录gc日志路径
-XX:+PrintGCDetails   #打印gc日志
-XX:+PrintGCDateStamps  #打印gc发生的具体时间
-XX:+PrintPromotionFailure  #打开了就知道是多大的新生代晋升到老生代引发的full gc
-XX:-UseBiasedLocking   #取消偏向锁
-XX:AutoBoxCacheMax=20000  #增大Integr cache
-XX:+AlwaysPreTouch  #启动时访问并置零内存页面
-Djava.security.egd=file:/dev/./urandom #此江湖偏方原因为Tomcat的SecureRandom显式使用SHA1PRNG算法时,初始因子默认从/dev/random读取会存在堵塞。额外效果是SecureRandom的默认算法也变成合适的SHA1了
-XX:+ExplicitGCInvokesConcurrent  #​full gc时,使用CMS算法,不是全程停顿,必选
-XX:+ParallelRefProcEnabled  #并行的处理Reference对象,如WeakReference,默认为false,除非在GC log里出现Reference处理时间较长的日志,否则效果不会很明显,但我们总是要JVM尽量的并行,所以设了也就设了
-XX:+UseConcMarkSweepGC  #老年代并发收集,CMS gc
-XX:CMSInitiatingOccupancyFraction=75  #老年代内存空间使用到75%时执行CMS收集,以确保年老代有足够的空间接纳来自年轻代的对象,避免Full GC的发生。
-XX:+UseCMSInitiatingOccupancyOnly  #在年老代使用了初始化的比例后并发收集器启动收集
-XX:-CMSClassUnloadingEnabled  #在CMS中清理永久代中的过期的Class而不等到Full GC
-XX:+CMSScavengeBeforeRemark
-XX:+HeapDumpOnOutOfMemoryError   #发生OOM时创建堆内存转储文件
-XX:HeapDumpPath=/usr/local/tomcat/logs  #发生OOM时创建堆内存转储文件路径,在容器环境中,输出4G的HeapDump在普通硬盘会造成20秒以上的硬盘IO跑满,容易影响同一宿主机上所有其它容器
-XX:OnOutOfMemoryError=/usr/local/tomcat/bin/stop.sh  #发生OOM记录内存转储文件后。执行的操作,可以重启或者停止服务
-XX:ErrorFile=/usr/local/tomcat/logs/hs_err_%p.log  #jvm crash时hotspot会生成一个error文件,提供jvm状态信息
-XX:+PrintCommandLineFlags  #将启动参数输出到catalina.out
-XX:+PrintFlagsFinal  #启动后打印默认和更改过的参数值到catalina.out
-XX:-OmitStackTraceInFastThrow 
-Duser.timezone=Asia/Shanghai  #用户所在时区
-Djavax.servlet.request.encoding=UTF-8
-Djavax.servlet.response.encoding=UTF-8
-Dfile.encoding=UTF-8
-Duser.country=CN
-Duser.language=zh
-Djava.awt.headless=true
-Dcom.sun.management.jmxremote.port=1099    #以下参数为开启jmx远程给监控系统连接
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Djava.rmi.server.hostname=127.0.0.1"

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值