0


JVM调优总结--压力测试

0.跟本文相关的面试题

JVM参数设置:

1.查看JVM进程:

C:\Users\ThinkPad>jps
33360 Launcher
4532
18696 MainClientBootStrap
21864 Launcher
18380 MainServerBootStrap
19212 Jps

2.Linux查看进程的线程信息

参考文章:Linux查看进程的线程信息_慕城南风的博客-CSDN博客_linux查看线程

(1). ps指令:

在ps命令中,“-T”选项可以查看线程信息。下面的命令列出了由进程号为<pid>的进程中的所有线程。

ps -T -p <pid>

SID”栏表示线程ID,而“CMD”栏则显示了线程名称。

[root@zhihuiyingxiao-dev-68499-04i2g ~]# ps -T -p 20754
  PID  SPID TTY          TIME CMD
20754 20754 ?        00:00:00 java
20754 20755 ?        00:00:17 java
20754 20756 ?        00:00:30 java
20754 20757 ?        00:00:30 java
20754 20759 ?        00:02:11 java
20754 20760 ?        00:00:00 java
20754 20761 ?        00:00:02 java
20754 20762 ?        00:00:00 java
20754 20774 ?        00:02:13 java
20754 20800 ?        00:15:19 java
20754 20801 ?        00:17:50 java
20754 20802 ?        00:03:39 java
20754 20803 ?        00:00:07 java
20754 20804 ?        00:00:00 java
20754 20805 ?        00:00:11 java
20754 20806 ?        00:01:07 java
20754 20807 ?        00:00:01 java
20754 20808 ?        00:15:17 java
20754 20809 ?        00:00:12 java
20754 20810 ?        00:00:02 java
20754 20811 ?        00:01:04 java
..................................

(2). pstree指令

// 打印所有进程及其线程
pstree -p 
// 打印某个进程的线程数
pstree -p {pid} | wc -l

(3). top指令

top命令可以实时显示各个线程情况。要在top输出中开启线程查看,请调用top命令的“-H”选项,该选项会列出所有Linux线程。在top运行时,你也可以通过按“H”键将线程查看模式切换为开或关。

**加了-H参数后,top的每一行就不是显示一个进程,而是一个线程。 **

top -H

要让top输出某个**特定进程<pid>**并检查该进程内运行的线程状况:

top -H -p <pid>

(4)top查看CPU使用率(重要)

参看下面这篇文章:

linux下用top命令查看cpu利用率超过100%_huangshanchun的博客-CSDN博客_top命令查看cpu使用率

下图中我们看到了什么?CPU使用率达到176.4%+51.8%+......???不要害怕,这是所有CPU的使用率加起来得到的值。

运行top后按大键盘1看看,可以显示每个cpu的使用率,top里显示的是把所有使用率加起来。

按下1后可以看到我的机器的CPU是16核的。%Cpu0,%Cpu1 ---> %Cpu15。

这里我们也可以查看一下CPU信息:在命令行里输入:

cat /proc/cpuinfo

3.查看JVM 的gc信息

(1) 第一种方式

(2) 第二种方式

参考文章:JVM查看gc情况_本本的香菜的博客-CSDN博客_jvm查看gc

jstat -gcutil pid interval(ms)

S0: 新生代中Survivor space 0区已使用空间的百分比

S1: 新生代中Survivor space 1区已使用空间的百分比
E: 新生代已使用空间的百分比
O: 老年代已使用空间的百分比
M: 方法区已使用空间的百分比

YGC: 从应用程序启动到当前,发生Yang GC 的次数

YGCT: 从应用程序启动到当前,Yang GC所用的时间【单位秒】

FGC: 从应用程序启动到当前,发生Full GC的次数

FGCT: 从应用程序启动到当前,Full GC所用的时间

GCT: 从应用程序启动到当前,用于垃圾回收的总时间【单位秒】

4.查看设置JVM参数:

(1).查看JVM所有参数:

jinfo pid
C:\Users\ThinkPad>jinfo 18380
Attaching to process ID 18380, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.291-b10
Java System Properties:

java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 25.291-b10
sun.boot.library.path = C:\Program Files\Java\jdk1.8.0_291\jre\bin
java.vendor.url = http://java.oracle.com/
java.vm.vendor = Oracle Corporation
path.separator = ;
file.encoding.pkg = sun.io
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
sun.os.patch.level =
sun.java.launcher = SUN_STANDARD
user.script =
user.country = CN
user.dir = H:\eclipse-workspace\netty-learning
java.vm.specification.name = Java Virtual Machine Specification
java.runtime.version = 1.8.0_291-b10
java.awt.graphicsenv = sun.awt.Win32GraphicsEnvironment
os.arch = amd64
java.endorsed.dirs = C:\Program Files\Java\jdk1.8.0_291\jre\lib\endorsed
line.separator =

java.io.tmpdir = C:\Users\ThinkPad\AppData\Local\Temp\
java.vm.specification.vendor = Oracle Corporation
user.variant =
os.name = Windows 10
sun.jnu.encoding = GBK
java.library.path = C:\Program Files\Java\jdk1.8.0_291\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files (x86)\VMware\VMware Workstation\bin\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\MySQL\MySQL Server 8.0\bin\;F:\java\apache-maven-3.8.4\bin;C:\Program Files\Git\cmd;C:\Program Files\Java\jdk1.8.0_291\bin;C:\Program Files\Java\jdk1.8.0_291\jre\bin;F:\Program Files\nodejs\;C:\ProgramData\chocolatey\bin;C:\Users\ThinkPad\AppData\Local\Programs\Python\Python39\Scripts\;C:\Users\ThinkPad\AppData\Local\Programs\Python\Python39\;C:\Program Files\MySQL\MySQL Shell 8.0\bin\;C:\Users\ThinkPad\AppData\Local\Microsoft\WindowsApps;;C:\Program Files\JetBrains\IntelliJ IDEA 2019.2.4\bin;;C:\Users\ThinkPad\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\ThinkPad\AppData\Roaming\npm;.
sun.nio.ch.bugLevel =
java.specification.name = Java Platform API Specification
java.class.version = 52.0
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
os.version = 10.0
user.home = C:\Users\ThinkPad
user.timezone = Asia/Shanghai
java.awt.printerjob = sun.awt.windows.WPrinterJob
file.encoding = UTF-8
java.specification.version = 1.8
user.name = ThinkPad
java.class.path = C:\Program Files\Java\jdk1.8.0_291\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\rt.jar;H:\eclipse-workspace\netty-learning\target\classes;F:\java\maven-repo\io\netty\netty-all\4.1.20.Final\netty-all-4.1.20.Final.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2021.3.1\lib\idea_rt.jar
java.vm.specification.version = 1.8
sun.arch.data.model = 64
sun.java.command = com.bruce.dubboLearn.provider.MainServerBootStrap
java.home = C:\Program Files\Java\jdk1.8.0_291\jre
user.language = zh
java.specification.vendor = Oracle Corporation
awt.toolkit = sun.awt.windows.WToolkit
java.vm.info = mixed mode
java.version = 1.8.0_291
java.ext.dirs = C:\Program Files\Java\jdk1.8.0_291\jre\lib\ext;C:\Windows\Sun\Java\lib\ext
sun.boot.class.path = C:\Program Files\Java\jdk1.8.0_291\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\rt.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\sunrsasign.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_291\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_291\jre\classes
java.vendor = Oracle Corporation
file.separator = \
java.vendor.url.bug = http://bugreport.sun.com/bugreport/
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
sun.desktop = windows
sun.cpu.isalist = amd64

VM Flags:
Non-default VM flags: -XX:CICompilerCount=4 -XX:InitialHeapSize=266338304 -XX:MaxHeapSize=4229955584 -XX:MaxNewSize=1409810432 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=88604672 -XX:OldSize=177733632 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
Command line:  -javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2021.3.1\lib\idea_rt.jar=50717:C:\Program Files\JetBrains\IntelliJ IDEA 2021.3.1\bin -Dfile.encoding=UTF-8

(2).查看JVM单一参数:

#jinfo -flag MaxHeapSize 18380

-XX:MaxHeapSize=4229955584

(3).设置堆转储文件:

除了可以设置在内存溢出的时候进行堆转储,还可以设置在发生FUll GC的时候进行堆转储。

https://www.jianshu.com/p/0088673d8f0e

5.K8s集群环境

在k8s集群环境下,Pod内存资源是怎样分配的?堆内存占多少呢?

假设Pod有2G的内存资源,如果不设置JVM堆内存大小,那么JVM堆的默认大小是Pod资源的 1/4,也就是说如果Pod内存资源是2G,那么JVM堆大小是500M左右;如果Pod是4G,那么JVM堆大小是1G。

Pod内存资源是2G,如果将JVM堆大小设置为1G,那么程序是启动不了的,因为Pod作为一个虚拟机,并不是所有的内存资源都可以给JVM使用的。

[root@shuziyingxiao-prod-05912-hpi30 ~]# kubectl exec -it wit-crm-58f7bb9b75-dcqjk -n wit - 
 -- /bin/sh
/ # 
/ # jps
8 app.jar
11085 Jps
/ # 
/ # jinfo -flag MaxHeapSize 8
-XX:MaxHeapSize=536870912
/ # 
/ # jstat -gcutil 8 2000
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
 47.92   0.00  69.32  84.04  87.84  81.24   9816   70.244    10    5.398   75.643
 47.92   0.00  69.83  84.04  87.84  81.24   9816   70.244    10    5.398   75.643
 47.92   0.00  69.85  84.04  87.84  81.24   9816   70.244    10    5.398   75.643
 47.92   0.00  71.56  84.04  87.84  81.24   9816   70.244    10    5.398   75.643
 47.92   0.00  71.72  84.04  87.84  81.24   9816   70.244    10    5.398   75.643
 47.92   0.00  71.73  84.04  87.84  81.24   9816   70.244    10    5.398   75.643
 47.92   0.00  71.82  84.04  87.84  81.24   9816   70.244    10    5.398   75.643
 47.92   0.00  73.33  84.04  87.84  81.24   9816   70.244    10    5.398   75.643
 47.92   0.00  73.69  84.04  87.84  81.24   9816   70.244    10    5.398   75.643
 47.92   0.00  73.70  84.04  87.84  81.24   9816   70.244    10    5.398   75.643
 47.92   0.00  73.90  84.04  87.84  81.24   9816   70.244    10    5.398   75.643

6.FGC效果实现:

1.实现FGC效果

怎样写代码,实现FGC的效果呢?

这里给出一个例子:

package com.example.demo.controller;

import com.example.demo.util.CreateUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("hello")
public class TestController {

    @GetMapping("world")
    public String getResponse(){
        Object[] objects = new Object[600*1024];
        for (int i=0; i< 600*1024 ; i++){
            objects[i] = new Object();
        }
//        CreateUtil.add();
        System.out.println("hello, world, bruce!");
        return "hello, world - 20220505!";
    }
}

new一个足够大的数组,然后用new object填充,每次请求都是这样的操作。

然后打开jmeter,1000个并发线程去访问上面的API

产生FGC:

2.怎样防止出现FGC?

增加JVM堆内存,继续观察FGC情况

java -Xms1024M -Xmx1024M ...........

7. jmeter并发压力测试

1.线程组设置:

2.Http Request

3.Http Header Manager

4.Response Code断言

5.结果查看:

察看结果数,列出每个请求结果。

6. 聚合报告:

展示统计数据:

5.JVM FGC查询

在jmeter压力测试下,FGC的情况如下(不同JVM堆内存情况下,肯定是不同的)

# jinfo -flag MaxHeapSize 8
-XX:MaxHeapSize=536870912
/ #
/ # jstat -gcutil 8 2000
 99.79   0.00  53.20  77.92  93.02  89.91   2699   26.561    19   10.513   37.074
  0.00   1.32  44.46  82.09  93.02  89.91   2706   26.757    19   10.513   37.269
.................................................................................
  0.00  99.76   4.63  95.18  93.02  89.91   2756   27.520    19   10.513   38.032
  0.00  25.46   0.00  74.81  93.02  89.91   2762   27.716    20   11.057   38.773
  2.08   0.00  27.42  74.86  93.02  89.91   2769   27.825    20   11.057   38.882
  2.08   0.00  91.13  74.89  93.02  89.91   2775   27.925    20   11.057   38.982
.................................................................................
 71.88   0.00  11.92  95.90  93.02  89.91   2897   29.400    20   11.057   40.457
 47.41   0.00   6.89  74.85  93.02  89.91   2901   29.517    21   11.619   41.136
.................................................................................
100.00   0.00  48.90  83.38  93.02  89.91   2949   30.187    21   11.619   41.806
  0.00   2.08  93.24  89.58  93.02  89.91   2956   30.352    21   11.619   41.970
 99.81   0.00   0.00  97.09  93.02  89.91   2963   30.521    22   11.619   42.139
.................................................................................
 99.45   0.00  32.35  84.58  93.02  89.91   3005   31.117    22   12.218   43.335
 36.08   0.00 100.00  87.78  93.02  89.91   3011   31.194    22   12.218   43.411
  0.00  27.15   0.00  98.47  93.02  89.91   3018   31.370    23   12.218   43.588
.................................................................................
  0.00  43.18  42.41  91.09  93.02  89.91   3066   31.986    23   12.804   44.790
 54.94   0.00  45.68  74.82  93.02  89.91   3071   32.132    24   13.350   45.482
 10.42   0.00  38.28  77.59  93.02  89.91   3079   32.228    24   13.350   45.578
.................................................................................
  0.00   6.25  87.94  94.80  93.02  89.91   3162   33.351    24   13.350   46.701
 99.25 100.00 100.00 100.00  93.02  89.91   3167   33.507    25   13.350   46.858
  0.00  11.11   4.60  75.91  93.02  89.91   3169   33.532    25   13.911   47.443
.................................................................................
  0.00  12.50  43.05  96.73  93.02  89.91   3263   34.767    25   13.911   48.678
 99.25 100.00 100.00 100.00  93.02  89.91   3268   34.859    26   13.911   48.771
 45.14   0.00  25.03  77.36  93.02  89.91   3273   35.003    26   14.471   49.474
 44.21   0.00  61.38  82.77  93.02  89.91   3279   35.223    26   14.471   49.695
  0.69   0.00  48.51  91.25  93.02  89.91   3285   35.307    26   14.471   49.778

8.几点性能测试思路

1.性能测试4点想法:

  1. 微服务系统里面包含多个微服务,有些用户请求可能经过多个微服务处理,在做性能测试的时候,可以使用skywalking微服务调用链路追踪工具,看看哪个微服务响应慢,然后去提升这个微服务的性能。
  2. 提升微服务性能的时候,要想办法提高每个实例的性能,就像我们前几天讨论的,先采用最简单的方式,就是增加JVM堆内存,减少FGC频率。不能简单的增加这个微服务的实例数量,毕竟提升每个实例性能,比简单的增加实例数量消耗的资源要少,不然的话,服务器资源迟早不够用。
  3. 性能测试的时候,会不会发生内存溢出这样的问题,怎么抓这样的问题? 可以通过增加JVM启动参数的方式,在发生内存溢出的时候,生成堆转储文件,我们可以对这个堆转储文件进行分析。
  4. .对于系统承载不了的请求,要用sentinel做限流 熔断 降级

2.简述:

  1. 使用skywalking监控相应慢的微服务,并对其进行优化
  2. 优化微服务的时候,要以优化单实例性能为主,减少实例数量,避免过度消耗服务器资源
  3. 内存溢出监控
  4. sentinel限流熔断降级

参考文章:

如何查看Linux的内存使用率 - Hackerman - 博客园 (cnblogs.com)

标签: java

本文转载自: https://blog.csdn.net/wdquan19851029/article/details/124588707
版权归原作者 困知勉行1985 所有, 如有侵权,请联系我们删除。

“JVM调优总结--压力测试”的评论:

还没有评论