【JVM】调优工具

这里简单介绍一下各种调优用到的工具

一,环境准备

首先我们需要准备好Java环境,和win上的jdk环境(图形化界面如jconsole只有jdk中有)。

有这样一个类Prolem,每个线程都会带来100个垃圾对象,线程new完100个垃圾对象基本就结束了,等待3秒后重新开始制造新的垃圾对象,而线程池中有50个这样的线程。毫无疑问,这样会造成JVM中内存的占用的彪高。


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 Problem {

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

        public void m() {

        }
    }

    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 void modelFit(){
        List<CardInfo> taskList = getAllCardInfo();
        taskList.forEach(info -> {
            // do something
            executor.scheduleWithFixedDelay(() -> {
                //do sth with info
                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;
    }
}

将这个类复制到Linux中,javac Problem编译Problem类到当前文件夹下,然后使用java -Xms20M -Xmx20M -XX:+PrintGC -XX:+PrintGCDetails Problem,指定堆大小为20M不变,这样使得堆GC频率会很频繁,-XX:+PrintGCDetails开启GC细节日志,直接启动Problem中的主方法。

二,主要工具

在收到报警后,如何检查问题出在哪里呢?

top命令,查看本台Linux机器中资源占用情况,可以看到CPU占满的是pid为27282的Java进程。内存没有显示占用多少是因为我指定了堆内存为20M,其实内存此时已经占用满了。

在这里插入图片描述

top -Hp Pid 命令,top -Hp加上Java进程的pid,展示Java内部线程的资源占用情况。在这个栗子中可以看到cpu很高,是因为垃圾占用一直很高,于是GC线程一直工作。

在这里插入图片描述

GC日志,这里的GC日志是我们直接使用-XX:+PrintGCDetails在前台打印的日志,生产看JVM日志要去分析jmap的dump文件。可以看到先是YGC,回收速度小于垃圾对象制造速度,于是很快就变成了Full GC,后期甚至还会堆内存溢出。

在这里插入图片描述

在这里插入图片描述

jps,列出Java进程的进程ID和主类名称。这个命令通常用于查看正在运行的Java进程,以便进行监控或管理。通过这个命令查看Problem类的进程的pid,相比top,快速便捷,方便后面使用jmap等工具。

在这里插入图片描述

jstack定位线程堆栈信息,看到线程在等待

在这里插入图片描述

jmap,比较重要的分析工具。

jmap -histo pid | head numbermap - histo命令用于生成Java堆内存中实例对象数量及占用内存的直方图,显示堆中各个对象类型的数量和大小。后面跟上管道符和head命令,展示占用靠前多少的对象。

在这里插入图片描述

jmap -dump,使用jmap去dump堆栈信息。分析dump文件,如果是上G的文件,直接用vim太Low了效率也低。。

分析dump文件的工具,eclipse有MAT(免费),idea有JProfiler插件(收费,499美元),好货不便宜啊。。此外也可以使用jvirsualvm来进行dump文件分析,jhat也可以,但是比较古老。

在这里插入图片描述
jmap -heap pid,打印堆内存信息。

[root@192 code]# jmap -heap 26983
Attaching to process ID 26983, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.361-b09

using thread-local object allocation.
Parallel GC with 4 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 209715200 (200.0MB)
   NewSize                  = 69730304 (66.5MB)
   MaxNewSize               = 69730304 (66.5MB)
   OldSize                  = 139984896 (133.5MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 16777216 (16.0MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 4294963200 (4095.99609375MB)
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 52428800 (50.0MB)
   used     = 18120048 (17.280624389648438MB)
   free     = 34308752 (32.71937561035156MB)
   34.561248779296875% used
From Space:
   capacity = 8650752 (8.25MB)
   used     = 8639984 (8.239730834960938MB)
   free     = 10768 (0.0102691650390625MB)
   99.87552527225378% used
To Space:
   capacity = 8650752 (8.25MB)
   used     = 0 (0.0MB)
   free     = 8650752 (8.25MB)
   0.0% used
PS Old Generation
   capacity = 139984896 (133.5MB)
   used     = 14180352 (13.5234375MB)
   free     = 125804544 (119.9765625MB)
   10.129915730337078% used

1230 interned Strings occupying 70952 bytes.

jmap -clstats pid,打印Java进程的元数据信息,也就是方法区的信息

在这里插入图片描述

arthas,阿里的开源工具,用attach的方式监控,相当于对流进行代理,而不是图形化界面实时命令,因此arthas对系统的负荷很小,命令行界面也比较友好。

安装arthas[3],安装很简单,直接下载jar包后启动即可。

curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar

回车后,arthas会显示检测到的Java进程,按顺序从1开始排列,我们输入1,选择把arthas挂到第一个进程上。看到下面的ARTHAS图形,启动成功。

在这里插入图片描述
arthas启动后(在启动arthas之前,我将Java进程停掉,堆内存指定为200M并重新启动,不然20M容易导致arthas挂失败)。可以看到Linux用户从root变为了arthas,arthas用户可以使用如下命令。

jvm,类似于jinfo的效果,显示jvm的各种参数信息

在这里插入图片描述
在这里插入图片描述
dashboard,监控大盘,可以看到线程、内存的各种状态

在这里插入图片描述

thread,只查看进程

在这里插入图片描述

jad,反编译,定位动态代理生成类的问题、版本问题等。

在这里插入图片描述

redefine,热替换,可以在不用重新部署项目的情况下,将代码替换掉。但是有一些限制,只能改方法实现(方法已经运行完成),不能改方法名, 不能改属性。

比如我们有2个类如下:

import java.io.IOException;

public class TestRedefine {

    public static void main(String[] args) throws IOException {
        while (true){
            System.in.read();
            new RedefineNode().out();
        }
    }

}
public class RedefineNode {

    public static void out(){
        System.out.println(1);
    }

}

将其启动后,输入字母,只能得到输出1.

[root@192 code]# java TestRedefine
a
1
1
a
1
1
s
1
1

现在我们直接vim类RedefineNode ,将1换成2,并且javac RedefineNode.java。编译成class文件。最终在arthas中将其热替换,再用反编译查看代码,发现已经换成了2.

在这里插入图片描述

测试输入输出,输出变成了2,热替换成功。

[root@192 code]# java TestRedefine
a
1
1
a
1
1
s
1
1
a
2
2
d
2
2
s
2
2

heapdump /root/gc2024051401.hprof,arthas对jvm进行dump,格式要为hprof。

配合jdk工具jhat对dump文件进行分析,

在这里插入图片描述
Linux ip+7000端口,打开jhat网址

在这里插入图片描述
jhat的各项是按照字母顺序排列的,直接拉到最下方,others才是有用的。

在这里插入图片描述

如jhat统计类的实例对象数量

在这里插入图片描述

OQL,通过语句查询想要的结果
在这里插入图片描述
或者也可以把dump文件拿出来,用jvirsualvm的装入,载入dump文件来分析。比如这里我用finalshell,将dump文件下载后,使用jvrisualvm分析。

在这里插入图片描述

下载在桌面自动创建的文件夹中,将其装入,查看dump文件中的信息,可以看到哪个对象是最多的。

在这里插入图片描述

三,作用不大的工具

jinfo pid,可以看到一些java进程的配置信息,作用不大

在这里插入图片描述
jstat -gc pid。每500毫秒打印一次gc日志,但是信息很抽象,比较晦涩

在这里插入图片描述
jconsole,下图能看到一些类似jinfo的信息。jconsole等调试工具在jdk中包含,在win中远程连接Linx即可,但是远程连接图形化界面,相当于实时使用命令监控,对线上系统有很大压力,因此图形化界面如jconsole、jvirsualvm不建议线上使用。jconsole在连接时有一些注意事项【注1】。

在这里插入图片描述

能看到内存在节节升高,回收完短暂的掉下去一点,然后又升高,但是没啥用,分析不出来问题
在这里插入图片描述
jvirsualvm,也是jdk中自带。使用时也是有一些注意事项,放到最后【注2】。

可以看到jvirsualvm终于比jconsole好用一些了,能够看到内存中哪些对象最多,但是如果业务代码多且复杂,可能无法借此分析出结果。不过总归比jconsole好一些,同样,jvirsualvm不推荐线上使用。

在这里插入图片描述
在这里插入图片描述
中止Linux上的jstatd,就可以终止jvirsualvm的可视化。
在这里插入图片描述

【注1】
连接jconsole的Java进程,在启动时,需要加上以下参数,以支持JMX协议。ip换成Linux的,port不用换,是JMX协议的远程通讯端口。

java -Djava.rmi.server.hostname=192.168.18.128 
-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=11111 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false Problem

自己的虚拟机如果防火墙或者iptables开启,可以关闭。生产上开放出端口即可。
然后在win上的jconsole上连接192.168.18.128:11111。

在这里插入图片描述

【注2】
Linux上,进入JAVA_HOME的bin目录下,

vi jstatd.all.policy 

在其中保存如下内容:

grant codebase "file:${java.home}/../lib/tools.jar" {
   permission java.security.AllPermission;
};

启动jstatd,开启jstatd后,此时就可以用win的jvirsualvm连接Java进程了

jstatd -J-Djava.security.policy=D:\tools.policy

在这里插入图片描述

参考文章:
[1],使用jvisualvm的jstatd方式远程监控Java程序
[2],jstatd 启动报错解决:Could not create remote
object
[3],arthas/README_CN.md

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

智慧公厕,提升公共厕所管理效率的信息化变革

现代社会中&#xff0c;公共厕所的管理成为一个不可忽视的问题。随着城市化进程的加快&#xff0c;人们对公厕的需求日益增加&#xff0c;但公厕的管理却面临诸多困难。为了解决这一问题&#xff0c;智慧公厕应运而生&#xff0c;通过信息化的变革&#xff0c;提高公厕的管理效…

QT函数整理

目录 1. 适应高分辨率函数 1. 适应高分辨率函数 自动适应调整设备安装QT的UI分辨率&#xff1a; QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 加载位置&#xff1a;

第四届辽宁省大学生程序设计竞赛

比赛经历&#xff1a;2024.5.14简单vp了一个小时只写出了签到题4个然后跑路了 补题&#xff1a;感觉其他题有点太抽象了主要补了一题&#xff0c;在区间问题中数据结构的使用 比赛链接[点我即可] 目录 A.欢迎来到辽宁省赛 B.胜率 F.隔板与水槽 H.取石子 L.区间与绝对值 …

第188题|幂级数的展开的常规方法(一)|武忠祥老师每日一题

解题思路&#xff1a;求幂级数有两种方法&#xff0c;一种是直接法&#xff0c;这里显然不太好求&#xff0c;还有一种是利用现有展开式展开&#xff0c;我们看到分母 可以分解因式成(x6)(x-1),进而拆解成一次式。拆解成一次式的目的是为了使用一下两个展开式。 第一步&#xf…

NARUTO 复现记录

1 环境配置 下载项目&#xff0c;一定要 git 下载全项目&#xff0c;下载完后要检查third_parities 里面的coslam和neural_slam_eval 文件全不全。 git clone --recursive https://github.com/oppo-us-research/NARUTO.git 环境配置 注意 bash scripts/installation/conda…

【哔哩哔哩下载】Bilidown,B站下载工具网站,永久免费使用NO.98

本文一共:448 个字,需要阅读:2 分钟,更新时间:2024年5 月14日,部分内容具有时效性,如有失效请留言,阅读量:0 输入B站视频网址就可以下载了 除了可以下载视频&#xff0c;还能获取弹幕、查看封面&#xff0c;如果你想解锁1080P画质&#xff0c;就需要扫码登录。 点击右下角的齿…

python “名称空间和作用域” 以及 “模块的导入和使用”

七、名称空间和作用域 可以简单理解为存放变量名和变量值之间绑定关系的地方。 1、名称空间 在 Python 中有各种各样的名称空间&#xff1a; 全局名称空间&#xff1a;每个程序的主要部分定义了全局的变量名和变量值的对应关系&#xff0c;这样就叫做全局名称空间 局部名称…

0508GoodsContent的Maven项目

0508GoodsContent的Maven项目包-CSDN博客 数据库字段 页面需求

OFDM802.11a的FPGA实现(十五)短训练序列:STS(含Matlab和verilog代码)

原文链接&#xff08;相关文章合集&#xff09;&#xff1a;OFDM 802.11a的xilinx FPGA实现 1.前言 在之前已经完成了data域数据的处理&#xff0c;在构建整个802.11a OFDM数据帧的时候&#xff0c;还剩下前导码和signal域的数据帧&#xff0c;这两部分的内容。 PLCP的前导部分…

八年前端开发之路中遇到的一些实用技巧分享——代码思路及通用场景

在开发中比较有用的代码思路 1. 链式编程2. 高阶函数应用-(添加数据并提供删除方法)3. 利用Promise链切入&#xff08;延迟执行&#xff09;4. 通过中间层来解决问题&#xff08;装饰者模式&#xff09;5. 单例模式 1. 链式编程 所谓链式编程即是函数调用后返回对象本身 let …

LoRA Land: 310个经微调的大语言模型可媲美GPT-4

摘要 低秩自适应 (LoRA) 已成为大语言模型 (LLM) 参数有效微调 (PEFT) 中最广泛采用的方法之一。LoRA 减少了可训练参数的数量和内存使用,同时达到了与全面微调相当的性能。该研究旨在评估在实际应用中训练和服务使用 LoRA 微调的 LLM 的可行性。首先,该研究测量了在 10 个基础…

搞什么副业可以月入过万?

月入过万的副业不是一件容易的事情&#xff0c;它需要你付出很多努力和时间。以下是一些可能能够实现月入过万的副业 1. 自媒体运营 通过开设自己的公众号、博客或YouTube频道&#xff0c;积累一定的粉丝和流量&#xff0c;然后通过广告、赞助、商品销售等方式赚取收入。 2. …

110份财务常用excel模板(个税、采购、报销、预算),超实用!

如果你还在为报表头疼&#xff0c;那你一定不能错过这篇干货满满的分享&#xff01; 个税报表 个人所得税&#xff0c;听起来就头大&#xff1f;别担心&#xff0c;掌握这些技巧&#xff0c;轻松搞定&#xff01; - 记录员工收入&#xff0c;确保数据准确无误 - 计算应纳税…

【Redis7】10大数据类型之Bitfield类型

文章目录 1. Bitfield简介2. BITFIELD key [GET type offset]3. BITFIELD key [SET type offset value]4. BITFIELD key [INCRBY type offset increment] 1. Bitfield简介 Bitfield(位域)命令可以将一个 Redis 字符串看作是一个由二进制位组成的数组&#xff0c; 并对这个数组…

Qwen-VL环境搭建推理测试

引子 这几天阿里的Qwen2.5大模型在大模型圈引起了轰动&#xff0c;号称地表最强中文大模型。前面几篇也写了QWen的微调等&#xff0c;视觉语言模型也写了一篇CogVLM&#xff0c;感兴趣的小伙伴可以移步Qwen1.5微调-CSDN博客。前面也写过一篇智谱AI的视觉大模型&#xff08;Cog…

c++编程(11)——string类的模拟实现

欢迎来到博主的专栏——c编程 博主ID&#xff1a;代码小豪 文章目录 前言string类的模拟实现string的成员对象构造、赋值、析构访问成员对象的接口访问字符串中的元素迭代器对字符序列的插入、删除元素操作mystring类的相关操作 mystring类的所有模拟实现以及测试案例 前言 本…

云服务器和主机的区别

在今天的数字化时代&#xff0c;对于个人和企业来说&#xff0c;选择适当的服务器托管解决方案至关重要。然而&#xff0c;很多人对于云服务器和传统主机之间的区别不太清楚。本文将为您提供一个详细的指南&#xff0c;帮助您理解云服务器与主机之间的区别&#xff0c;以便您能…

光耦 IS314W中文资料 IS314W引脚图及功能说明

IS314W是一款IGBT/MOSFET输出型光耦&#xff0c;由Isocom公司制造。它主要用于驱动用于电机控制和电源系统变频器的功率IGBT和MOSFET。以下是该产品的部分功能和参数&#xff1a; - 两个独立的光耦输出通道 - 轨对轨输出电压 - 最大峰值输出电流&#xff1a;1.0A - 最小峰值输…

一文扫盲(13):电商管理系统的功能模块和设计要点

电商管理系统是一种用于管理和运营电子商务平台的软件系统。它提供了一系列功能模块&#xff0c;帮助企业进行商品管理、订单管理、会员管理、营销推广、数据分析等工作。本文将从以下四个方面介绍电商管理系统。 一、什么是电商管理系统 电商管理系统是一种集成了各种功能模块…

Moveit Noetic的运动规划组python接口

Moveit Noetic的运动规划组python接口 记录学习如何使用moveit的python API进行机械臂的控制 &#x1f680; 环境配置 &#x1f680; ubuntu 20.04ros noeticmoveit noetic法奥机械臂 frcobot_fr5 文章目录 Moveit Noetic的运动规划组python接口1. 设置moveit功能包2. 编写M…