JVM调优实战——jvm常用参数及方法

news2024/12/27 13:11:40

一、创建会内存溢出的程序

pom:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.fan</groupId>
  <artifactId>JVMTest</artifactId>
  <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>{Mainclass}</mainClass>
                                    <!-- 主类的位置,例如上图文件,主类配置应为: -->
                                    <mainClass>com.fan.T15_Fu11GC_Problem01</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <packaging>jar</packaging>

  <name>JVMTest</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
      <dependency>
          <groupId>org.apache.tomcat.embed</groupId>
          <artifactId>tomcat-embed-core</artifactId>
          <version>9.0.58</version>
      </dependency>
      <dependency>
          <groupId>backport-util-concurrent</groupId>
          <artifactId>backport-util-concurrent</artifactId>
          <version>3.1</version>
      </dependency>
  </dependencies>
</project>

Java:

package com.fan;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class T15_Fu11GC_Problem01 {
    private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(50, new ThreadPoolExecutor.DiscardOldestPolicy());

    public static void main(String[] args) throws Exception {
        executor.setMaximumPoolSize(50);
        for (; ; ) {
            modelFit();
            Thread.sleep(100);
        }
    }

    private static class CardInfo {
        BigDecimal price = new BigDecimal(0.0);
        String name = "张三";
        int age = 5;
        Date birihdate = new Date();

        public void m() {
        }
    }

    private static void modelFit() {
        List<CardInfo> taskList = getAllCardInfo();
        taskList.forEach(info -> {
            executor.scheduleWithFixedDelay(() -> {
                info.m();
            }, 2, 3, TimeUnit.SECONDS);
        });
    }

    private static List<CardInfo> getAllCardInfo() {
        List<CardInfo> taskList = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            CardInfo ci = new CardInfo();
            taskList.add(ci);
        }
            return taskList;
        }
}

打包 jar:

 将 JVMTest-1.0-SNAPSHOT.jar 包放到服务器中 

 二、启动 JVMTest-1.0-SNAPSHOT.jar

java -Xms200M -Xmx200M -XX:+PrintGC -jar JVMTest-1.0-SNAPSHOT.jar 

如图,随着时间的推移,GC每隔一段时间回收一次。

jvm排查常用命令: 

1. jps:该命令会显示所有的 java进程,这里我们的测试程序为 4869 jar

  

2. jinfo 进程号: 该命令显示 对应进程号进程的相关信息

[root@centos142 arthas]# jinfo 4869
Attaching to process ID 4869, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.333-b02
Java System Properties:

java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 25.333-b02
sun.boot.library.path = /usr/local/jdk1.8/jre/lib/amd64
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 = unknown
sun.java.launcher = SUN_STANDARD
user.country = CN
user.dir = /mnt/arthas
java.vm.specification.name = Java Virtual Machine Specification
java.runtime.version = 1.8.0_333-b02
java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment
os.arch = amd64
java.endorsed.dirs = /usr/local/jdk1.8/jre/lib/endorsed
java.io.tmpdir = /tmp
line.separator = 

java.vm.specification.vendor = Oracle Corporation
os.name = Linux
sun.jnu.encoding = UTF-8
java.library.path = /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
java.specification.name = Java Platform API Specification
java.class.version = 52.0
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
os.version = 3.10.0-1160.el7.x86_64
user.home = /root
user.timezone = 
java.awt.printerjob = sun.print.PSPrinterJob
file.encoding = UTF-8
java.specification.version = 1.8
user.name = root
java.class.path = JVMTest-1.0-SNAPSHOT.jar
java.vm.specification.version = 1.8
sun.arch.data.model = 64
sun.java.command = JVMTest-1.0-SNAPSHOT.jar
java.home = /usr/local/jdk1.8/jre
user.language = zh
java.specification.vendor = Oracle Corporation
awt.toolkit = sun.awt.X11.XToolkit
java.vm.info = mixed mode
java.version = 1.8.0_333
java.ext.dirs = /usr/local/jdk1.8/jre/lib/ext:/usr/java/packages/lib/ext
sun.boot.class.path = /usr/local/jdk1.8/jre/lib/resources.jar:/usr/local/jdk1.8/jre/lib/rt.jar:/usr/local/jdk1.8/jre/lib/sunrsasign.jar:/usr/local/jdk1.8/jre/lib/jsse.jar:/usr/local/jdk1.8/jre/lib/jce.jar:/usr/local/jdk1.8/jre/lib/charsets.jar:/usr/local/jdk1.8/jre/lib/jfr.jar:/usr/local/jdk1.8/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.cpu.isalist = 

VM Flags:
Non-default VM flags: -XX:CICompilerCount=2 -XX:InitialHeapSize=209715200 -XX:MaxHeapSize=209715200 -XX:MaxNewSize=69730304 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=69730304 -XX:OldSize=139984896 -XX:+PrintGC -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC 
Command line:  -Xms200M -Xmx200M -XX:+PrintGC

 例如,这里我们启动的程序使用的是  -Xms200M -Xmx200M -XX:+PrintGC

3.  jstat  -[gc] 进程号 [500]:该命令用来统计或跟踪 java 的进程信息。

(1)、动态观察 GC 情况(阅读 GC日志发现频繁GC 、arthas观察、jvisualVM、Jprofiler等)。

[root@centos142 arthas]# jstat -gc 4869
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
8192.0 8192.0  0.0    0.0   50688.0  50040.7   136704.0   136606.0  4864.0 4113.3 512.0  446.4       5    0.304  12      5.061    5.366

(2)、每500毫秒刷新一次,用来跟踪内存的增长过程

[root@centos142 arthas]# jstat -gc 4869 500
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
8192.0 8192.0  0.0    0.0   50688.0  50551.2   136704.0   136606.0  4864.0 4113.3 512.0  446.4       5    0.304  21      8.917    9.221
8192.0 8192.0  0.0    0.0   50688.0  50600.3   136704.0   136606.0  4864.0 4113.3 512.0  446.4       5    0.304  21      8.917    9.221
8192.0 8192.0  0.0    0.0   50688.0  50653.5   136704.0   136606.0  4864.0 4113.3 512.0  446.4       5    0.304  21      8.917    9.221
8192.0 8192.0  0.0    0.0   50688.0  50653.5   136704.0   136606.0  4864.0 4113.3 512.0  446.4       5    0.304  21      8.917    9.221
8192.0 8192.0  0.0    0.0   50688.0  50653.5   136704.0   136606.0  4864.0 4113.3 512.0  446.4       5    0.304  21      8.917    9.221
8192.0 8192.0  0.0    0.0   50688.0  50653.5   136704.0   136606.0  4864.0 4113.3 512.0  446.4       5    0.304  21      8.917    9.221
8192.0 8192.0  0.0    0.0   50688.0  50655.6   136704.0   136606.0  4864.0 4113.3 512.0  446.4       5    0.304  21      8.917    9.221
8192.0 8192.0  0.0    0.0   50688.0  50688.0   136704.0   136606.0  4864.0 4113.3 512.0  446.4       5    0.304  22      8.917    9.221
8192.0 8192.0  0.0    0.0   50688.0  50039.5   136704.0   136606.0  4864.0 4113.3 512.0  446.4       5    0.304  22      9.302    9.606

注意:图形界面用在测试的时候, 压测观察,而不是用在生产环境下定位OOM

4. jstack 4869 :该命令会显示 所有的线程(线程名、线程编号、线程优先级、操作系统级的优先级、线程的状态、线程的调用堆栈)的信息。如:多个线程的状态一直是 waiting on condition <XXX> ,则说明程序可能产生了死锁。

如何找到哪个线程持有这把锁?

       搜索 jstack dump 的信息,找<XXX>,看哪个线程持有这把锁 RUNNABLE。

[root@centos142 arthas]# jstack 4869
"pool-1-thread-45" #52 prio=5 os_prio=0 tid=0x00007fda34290000 nid=0x133d waiting on condition [0x00007fd9e2bea000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000000f82aef40> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
	at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
	at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
	at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:750)
"pool-1-thread-44" #51 prio=5 os_prio=0 tid=0x00007fda3428e000 nid=0x133c waiting on condition [0x00007fd9e2ceb000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000000f82c4af8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)

5. 系统级命令,top、top - Hp 进程号,top:查看当前进程占内存情况top - Hp 进程号:查看进程号中所有线程的内存、cup情况。

6. jmap 作用1:

        a、jmap -histo 进程号: 对当前 jvm 的所有对象进行分析,查看哪些类有多少个对象,占多大字节。

        b、jmap -histo 进程号 | head -20 :查看最占内存的前20个对象是哪些。

 jmap 作用2:

        jmap -dump:format=b,file=20230121.hprof 进程号  :产生一个java的整个堆内存的转储文件,对它进行分析。

注意:jmap是不可以在 生成环境下执行的,会产生一个很严重的后果:jmap会让 jvm 卡死在某个状态,线上系统,内存特别大,jmap执行期间会对进程产生很大影响,甚至卡顿(电商不适合)

        1:设定了参数HeapDump,OOM的时候会自动产生堆转储文件(不是很专业,因为多有监控,内存增长就会报警)

        2:很多服务器备份(高可用) ,停掉这台服务器对其他服务器不影响

        3:在线定位(一般小点儿公司用不到)
        4:在测试环境中压测(产生类似内存增长问题,在堆还不是很大的时候进行转储)

JVM常见排查流程:

1. 使用 top 找出哪个进程占用 cpu 比较高。

2. 使用 top -Hp 进程号,找到这个进程中哪个线程占用 cpu 高。

3. 根据线程编号通过 jstack 查看调用链路。一般分为俩种情况:

        a、vm GC

        b、业务线程,找业务方法占用高的

4. 如果是 vm GC,查看日志,看看原因是什么。如:访问量压力大(扩容机器)、内存回收不掉。

5. 一般启动项目的时候会设置,当进程出现 OOM后,自动生成dump文件。通过工具对dump文件进行分析。

java -Xms200M -Xmx200M -XX:+UseParallelGC -XX:+HeapDumpOnOutOfMemoryError java文件或 jar包

以上所有命令,都可以被 arthas 替代,arthas更方便、更全面!,学习arthas地址:

Arthas 入门到实战(一)快速入门_明湖起风了的博客-CSDN博客 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/175110.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Q_DISABLE_COPY、Q_DISABLE_MOVE、Q_DISABLE_COPY_MOVE用法详解及总结

1.前言在编程中&#xff0c;会用到某些资源&#xff0c;这些资源有的在整个应用程序期间是唯一的&#xff1b;是不能通过拷贝、赋值的方法存在多份的&#xff0c;如STL的std::unique_ptr指针指向的资源。现实中这样的资源有&#xff1a;文件指针、串口句柄等。试想如果存在多个…

TVM: End-to-End Optimization Stack for Deep Learning论文阅读

摘要 很多目前最为流行的深度学习框架&#xff0c;如 TensorFlow、MXNet、Caffe 和 PyTorch&#xff0c;支持在有限类型的服务器级 GPU 设备上获得加速&#xff0c;这种支持依赖于高度特化、供应商特定的 GPU 库。然而&#xff0c;专用深度学习加速器的种类越来越多&#xff0…

数据库系统概念 | 第四章:中级SQL

文章目录&#x1f4da; 连接表达式&#x1f407; 自然连接&#x1f407; 连接条件&#x1f955;natural条件&#x1f955;using 条件&#x1f955;on 条件&#x1f407; 内连接和外连接&#x1f955; 内连接inner join&#x1f955; 外连接outer join&#x1f343; 左外连接lef…

Web 应用渗透测试 00 - 信息收集

背景 这个系列写 Web 应用渗透测试相关的内容。此篇从信息收集开始&#xff0c;看一下 Web 应用端有哪些方面的信息值得渗透测试者去收集&#xff0c;能对后续的行动产生积极的影响。 Web 应用渗透测试 - 信息收集 security.txt 这个文件包含了网站的漏洞披露的联系方式。如…

Java面试题每日10问(18)

Miscellaneous Interview Questions 1. What are the advantages and disadvantages of object cloning? Advantage of Object Cloning You don’t need to write lengthy and repetitive codes. Just use an abstract class with a 4- or 5-line long clone() method.It is t…

二叉树的迭代遍历

二叉树的迭代遍历 前序遍历 基本思路 基本思路其实很简单, 使用递归遍历的时候, 一直是系统帮我们把其他数据压栈, 举个例子 > ans [5,4,6,2,1,null,null] 前序遍历的序列是: [5,4,2,1,6] , 栈的出入顺序是, 先入, 后出, 假如我们想要一个元素先出, 就要让它后入栈 基…

STC12驱动MLX90614红外测温模块在LCD1602显示

文章目录1、基本简介2、通信方式3、参考STC12例程参考文献1、基本简介 2、通信方式 通过芯片手册我们可以了解到这个模块的输出有PWM和SMBus方式&#xff0c;PWM长期做嵌入式开发的已经很熟悉了&#xff0c;那么什么是SMBus呢&#xff1f; SMBus&#xff08;系统管理总线&…

swift(3)

目录 while循环&#xff0c;repeat while循环 String基本操作 Array数组 Set集合 while循环&#xff0c;repeat while循环 import UIKitvar a0 while(a<5){print(a) }简单的while循环&#xff0c;我这一个循环下去&#xff0c;我playground直接被强制退出。 import UIK…

go的基本数据类型转换

目录 1.(整形转化)基本语法 2.小知识 3.基本数据类型和string的转换 A.fmt.Sprintf("%参数", 表达式) B. 使用 strconv 包的函数 4.string和基本数据类型转换 Go在不同类型的变量之间赋值时需要显示转换&#xff0c;不能自动转换 1.(整形转化)基本语法 A.不考…

Elasticsearch7.8.0版本高级查询—— 模糊查询文档

目录一、初始化文档数据二、模糊查询文档2.1、概述2.2、示例12.3、示例2一、初始化文档数据 在 Postman 中&#xff0c;向 ES 服务器发 POST 请求 &#xff1a;http://localhost:9200/user/_doc/1&#xff0c;请求体内容为&#xff1a; { "name":"zhangsan"…

LeetCode 1824. 最少侧跳次数

【LetMeFly】1824.最少侧跳次数 力扣题目链接&#xff1a;https://leetcode.cn/problems/minimum-sideway-jumps/ 给你一个长度为 n 的 3 跑道道路 &#xff0c;它总共包含 n 1 个 点 &#xff0c;编号为 0 到 n 。一只青蛙从 0 号点第二条跑道 出发 &#xff0c;它想要跳到…

SpringCloud(16):Zuul网关服务整合Swagger接口文档

手写Api文档的几个痛点 文档需要更新的时候&#xff0c;需要再次发送一份给前端&#xff0c;也就是文档更新交流不及时。接口返回结果不明确不能直接在线测试接口&#xff0c;通常需要使用工具&#xff0c;比如postman接口文档太多&#xff0c;不好管理1 springcloud快速集成 …

LINUX---进程间通信(IPC)

目录进程间通信&#xff08;IPC&#xff09;介绍&#xff1a;一、管道1、特点&#xff1a;2、原型&#xff1a;父子进程中的管道应用&#xff1a;FIFO1、特点2、原型三、消息队列ftok移除消息队列四.共享内存信号信号携带消息信号量微信QQ聊天就是进程间通信&#xff08;基于网…

大数据技术之Hadoop(MapReduce)

第1章 MapReduce概述 1.1 MapReduce定义 MapReduce是一个分布式运算程序的编程框架&#xff0c;是用户开发“基于Hadoop的数据分析应用”的核心框架。 MapReduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序&#xff0c;并发运行在一个H…

StructuredStreaming Sink

StructuredStreaming Sink Output Modes append 默认追加模式, 将新的数据输出&#xff0c;只支持简单查询 complete 完整模式&#xff0c;支持聚合和排序 update 更新模式&#xff0c;支持聚合不支持排序&#xff0c;没有聚合和append一样 下面这段操作&#xff0c;有聚合…

Python机器学习数据建模与分析——Numpy和Pandas综合应用案例:空气质量监测数据的预处理和基本分析

本篇文章主要以北京市空气质量监测数据为例子&#xff0c;聚集数据建模中的数据预处理和基本分析环节&#xff0c;说明Numpy和Pandas的数据读取、数据分组、数据重编码、分类汇总等数据加工处理功能。同时在实现案例的过程中对用到的Numpy和Pandas相关函数进行讲解。 文章目录数…

新的一年即将到来,分享2023年火爆的行业和值得做的副业兼职项目

明天就是除夕啦&#xff0c;小编还在努力工作着&#xff0c;分享完这一篇文章后&#xff0c;小编也要和家人朋友们一起好好休息下&#xff0c;过一个乐此不疲的春节。今天分享的主要是对明年行业的憧憬以及一些值得做的副业兼职项目&#xff0c;文章比较长&#xff0c;如果觉得…

Spring源码学习:setter循环依赖

1.案例&#xff1a;Component public class A {private B b;Autowiredpublic void setB(B b) {this.b b;}public B getB() {return b;}public void f(){System.out.println(b);} }Component public class B {private A a;Autowiredpublic void setA(A a) {this.a a;}public v…

Ubuntu 终端美化(oh-my-zsh)

文章目录Ubuntu 终端美化&#xff08;oh-my-zsh&#xff09;一、 环境准备二、 配置文件1、 主题2、 修改插件2.1 官方插件2.2 第三方插件Ubuntu 终端美化&#xff08;oh-my-zsh&#xff09; 一、 环境准备 这个美化教程适合于大多数的 Linux 系统&#xff0c;其实可以通用的。…

递归和分治(基础)

目录 一、递归的定义 1、什么时候会用到递归的方法 1. 定义是递归的 2. 数据结构是递归的 3. 问题的解法是递归的 2、应用递归的原则 3、递归调用顺序问题 1. 首先递归的过程可以总结为以下几点&#xff1a; 2. 递归工作栈 二、 递归和非递归的转化 1. 单向递归可…