综合门户网站源码,windows 2003 取消网站访问密码,边境网站建设方案,个人主页静态网站1. 要解决的问题
CPU 飚高#xff0c;内存溢出#xff0c;频繁 GC 2. CPU 飚高
2.1 定位问题的思路
首先找到 CPU 飚高的那个 Java 进程#xff0c;因为你的服务器会有多个 JVM 进程。
然后找到那个进程中的 “问题线程”#xff0c;
最后根据线程堆栈信息找到问题代码。…1. 要解决的问题
CPU 飚高内存溢出频繁 GC 2. CPU 飚高
2.1 定位问题的思路
首先找到 CPU 飚高的那个 Java 进程因为你的服务器会有多个 JVM 进程。
然后找到那个进程中的 “问题线程”
最后根据线程堆栈信息找到问题代码。最后对代码进行排查。2.2 具体操作
1. 通过 top 命令找到 CPU 消耗最高的进程并记住进程 ID。
2. 再次通过 top -Hp [进程 ID] 找到 CPU 消耗最高的线程 ID并记住线程 ID.
3. 通过 JDK 提供的 jstack 工具 dump 线程堆栈信息到指定文件中。具体命令jstack -l [进程 ID] jstack.log。
4. 由于刚刚的线程 ID 是十进制的而堆栈信息中的线程 ID 是16进制的因此我们需要将10进制的转换成16进制的并用这个线程 ID 在堆栈中查找。使用 printf %x\n [十进制数字] 可以将10进制转换成16进制。
5. 通过刚刚转换的16进制数字从堆栈信息里找到对应的线程堆栈。就可以从该堆栈中看出端倪。2.3 经验总结
1. 查看是否存在死循环 根据业务进行修复
2. C2 编译器执行编译时也会抢占 CPU 什么是 C2编译器呢当 Java 某一段代码执行次数超过10000次默认后就会将该段代码从解释执行改为编译执行也就是编译成机器码以提高速度。而这个 C2编译器就是做这个的。如何解决呢项目上线后可以先通过压测工具进行预热这样等用户真正访问的时候C2编译器就不会干扰应用程序了。
3. GC 线程导致的那么极有可能是 Full GC 那么就要进行 GC 的优化3. 内存问题内存的问题就是 GC 的问题排查
3.1 内存溢出
通过加上 -XX:HeapDumpOnOutOfMemoryError 参数
该参数作用是在程序内存溢出时输出 dump 文件再通过 dump 分析工具进行分析。参考JVM离线分析-使用MAT分析dump堆文件
3.2 内存没有溢出但 GC 不健康复杂
a. 通常一个健康的 GC 是什么状态呢
YGC 5秒一次左右每次不超过50毫秒FGC 最好没有CMS GC 一天一次左右。b. GC 的优化有2个维度一是频率二是时长
1. YGC频率我们看YGC首先看频率如果 YGC 超过5秒一次甚至更长说明系统内存过大应该缩小容量如果频率很高说明 Eden 区过小可以将 Eden 区增大但整个新生代的容量应该在堆的 30% - 40%之间edenfrom 和 to 的比例应该在 811左右这个比例可根据对象晋升的大小进行调整。时长如果 YGC 时间过长呢YGC 有2个过程一个是扫描一个是复制通常扫描速度很快复制速度相比而言要慢一些如果每次都有大量对象要复制就会将 STW 时间延长还有一个情况就是 StringTable 这个数据结构中存储着 String.intern 方法返回的常连池的引用YGC 每次都会扫描这个数据结构HashTable如果这个数据结构很大且没有经过 FGC那么也会拉长 STW 时长还有一种情况就是操作系统的虚拟内存当 GC 时正巧操作系统正在交换内存也会拉长 STW 时长。2. FGCFGC 我们只能优化频率无法优化时长因为这个时长无法控制。如何优化频率呢触发FGC的原因1 是 Old 区内存不够2 是元数据区内存不够3 是 System.gc() 4 是 jmap 或者 jcmd5 是CMS Promotion failed 或者 concurrent mode failure6 JVM 基于悲观策略认为这次 YGC 后 Old 区无法容纳晋升的对象因此取消 YGC提前 FGC优化的策略1. 通常优化的点是 Old 区内存不够导致 FGC。如果 FGC 后还有大量对象说明 Old 区过小应该扩大 Old 区2. 如果 FGC 后效果很好说明 Old 区存在了大量短命的对象优化的点应该是让这些对象在新生代就被 YGC 掉3. 通常的做法是增大新生代4. 如果有大而短命的对象通过参数设置对象的大小不要让这些对象进入 Old 区还需要检查晋升年龄是否过小。5. 如果 YGC 后有大量对象因为无法进入 Survivor 区从而提前晋升这时应该增大 Survivor 区但不宜太大。c. 需要一些工具知道 GC 的状况
1. jmap, jcmd工具的使用注意jmap 和 jcmd dump 文件的时候会触发 FGC 使用的时候注意场景
2. jstat该工具可以查看GC 的详细信息比如eden fromtoold 等区域的内存使用情况
3. jinfo该工具可以查看当前 jvm 使用了哪些参数并且也可以在不停机的情况下修改参数
4. dump堆内存文件离线分析
5. jdk11提供了jhsdb工具3.3 很重要的一点线上环境一定要带上 GC 日志。如何配置
参考1
# 必备
-XX:PrintGCDetails # 打印详细的GC日志信息。
-XX:PrintGCDateStamps #在GC日志中添加时间戳。
-XX:PrintGCID #打印GC的ID信息。
-XX:PrintTenuringDistribution #打印对象分布 为了分析 GC 时的晋升情况和晋升导致的高暂停不看对象年龄分布日志怎么行
-XX:PrintHeapAtGC # GC 后打印堆数据 每次发生 GC 时对比一下 GC 前后的堆内存情况更直观
-XX:PrintReferenceGC # 强引用/弱引用/软引用/虚引用/finalize 方法万一有问题不得打印出来看看
-XX:PrintGCApplicationStoppedTime # 打印 STW 时间暂停时间是 GC 最重要的指标肯定不能少# 可选
# 打印 safepoint 信息
# 进入STW阶段之前需要要找到一个合适的 safepoint 这个指标一样很重要
#非必选出现 GC 问题时最好加上此参数调试
-XX:PrintSafepointStatistics
-XX:PrintSafepointStatisticsCount1# GC日志输出的文件路径%t带上时间格式
-Xloggc:/path/to/gc-%t.log
# 开启日志文件分割
-XX:UseGCLogFileRotation
# 最多分割几个文件超过之后从头文件开始写
-XX:NumberOfGCLogFiles14
# 每个文件上限大小超过就触发分割
-XX:GCLogFileSize100M参考2数据中台的后端服务
-Xms2g #堆内存大小
-Xmx2g #最大堆内存大小
-XX:MetaspaceSize256m #元空间
-XX:MaxMetaspaceSize256m #最大元空间
-XX:MaxDirectMemorySize1g # 设置New I/Ojava.niodirect-buffer allocations的最大大小
-XX:SurvivorRatio10 #用于设置新生代中Eden区与Survivor区的空间比例
-XX:UseConcMarkSweepGC
-XX:CMSMaxAbortablePrecleanTime5000
-XX:CMSClassUnloadingEnabled
-XX:CMSInitiatingOccupancyFraction80
-XX:UseCMSInitiatingOccupancyOnly
-XX:ExplicitGCInvokesConcurrent
-Dsun.rmi.dgc.server.gcInterval2592000000
-Dsun.rmi.dgc.client.gcInterval2592000000
-XX:ParallelGCThreads8
-Xloggc:/data/middleLogs/admin-server_gc.log # gc日志配置
-XX:PrintGCDetails #打印详细的GC日志信息。
-XX:PrintGCDateStamps #在GC日志中添加时间戳。
-XX:PrintGCID #打印GC的ID信息。
-XX:HeapDumpOnOutOfMemoryError # OOM溢出配置
-XX:HeapDumpPath/admin-server_20230517175814_java.hprof # OOM dump文件存储路径
-Dfile.encodingUTF-8
-Dproject.nameadmin-server 4. STW是什么
参考 https://blog.csdn.net/guo20082200/article/details/134253092
5. 总结
以上是基本操作仅供参考需要学习更多事故排查技术比如排查 IO网络TCP 连接等等。