Java性能分析

news2024/9/27 15:18:05

0、问题代码:

代码问题其实很明显,但是这里主要是为了练习如何使用工具进行分析
所以最好先不要看代码,假装不知道程序逻辑,而是先通过工具去分析,再结合分析数据去看代码,从而推出问题点在哪

import java.util.ArrayList;
import java.util.List;

public class PerfTest {
    public static void main(String[] args) {
        //这里随机器的配置不同,可以适当把线程数量改大一点
        for (int i = 0; i < 4; i++) {
            int index = i;
            new Thread(() -> {
                while (true) {
                    for (int k = 0; k < 10; k++) {
                        List<String> list = new ArrayList<>();
                        String str = "" + index;
                        for (int j = 0; j < 10000; j++) {
                            str += "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"+j;
                        }
                        list.add(str);
                        System.out.println(index+"_"+k);
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }

                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();
        }

    }
}

运行:

javac PerfTest.java
java -Xmx100m PerfTest

通过jps命令找到PerfTest进程pid
top命令观察进程cpu使用情况
在这里插入图片描述
可以看到cpu使用超过400%

1、使用async-profiler进行分析

GitHub地址:https://github.com/async-profiler/async-profiler

wget https://github.com/jvm-profiling-tools/async-profiler/releases/download/v2.9/async-profiler-2.9-linux-x64.tar.gz
tar zxvf async-profiler-2.9-linux-x64.tar.gz
cd async-profiler-2.9-linux-x64
./profiler.sh -d 30 -f /tmp/flamegraph.html pid

把生成的flamegraph.html导出到本地用浏览器打开,如下图:
在这里插入图片描述
在这里插入图片描述
可以看出大部分cpu消耗都是在GC上

2、使用arthas分析

GitHub地址:https://github.com/alibaba/arthas

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

进入arthasshell后,使用thread命令:
在这里插入图片描述
也可以看出GC线程消耗了大量的CPU

把线程数改成20之后,效果更明显
在这里插入图片描述

直接使用jstat -gcutil pid命令,也能看出频繁的触发gull gc
在这里插入图片描述

3、代码优化

这里代码问题其实已经很明显了,是一个经典的String做字符串拼接导致的性能问题,直接用String做字符串拼接会产生大量不必要的String对象,导致频繁GC。
改为使用StringBuilder就可以大大缓解了

优化后的代码:

import java.util.ArrayList;
import java.util.List;

public class PerfTest2 {
    public static void main(String[] args) {
        for (int i = 0; i < 4; i++) {
            int index = i;
            new Thread(() -> {
                while (true) {
                    for (int k = 0; k < 10; k++) {
                        List<String> list = new ArrayList<>();
                        StringBuilder str = new StringBuilder(50*10000);
                        str.append(index);
                        for (int j = 0; j < 10000; j++) {
                            str.append("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"+j);
                        }
                        list.add(str.toString());
                        System.out.println(index+"_"+k);
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }

                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();
        }

    }
}

再次运行:

javac PerfTest2.java
java -Xmx100m PerfTest2

可以看到一个很明显的变化就是,控制台的输出速度快了很多,而且cpu占用也没那么高了,说明优化起到了很大的效果

然后再进一步测试,把线程数从4个改为20个
发现这时候cpu也开始变高,GC也变得很频繁
猜测是因为jvm分配的内存较小,导致内存紧张,频繁触发full gc(这里也可以用工具进行内存分析,但是懒得折腾了,后面有空再补充,如果有的话0.0)

通过java -Xmx1000m PerfTest2把内存调大十倍,再观察,cpu和gc都降下来了
(这里的操作和前面类似,就不再贴命令和截图了~~)

另外这里也延申一个问题,前面有问题的程序,也把内存调大十倍观察,这时候再观察:
1、cpu还是居高不下
2、gc大大缓解
3、程序执行性能得到提升,但还是很慢
这时候也只能结合arthas或者async profiler工具定位到cpu占用高的线程,结合阅读代码进行分析了

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

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

相关文章

代码随想录NO50 |动态规划_leetcode 392.判断子序列 115.不同的子序列

动态规划_leetcode 392.判断子序列 115.不同的子序列今天继续子序列&#xff01; 392.判断子序列 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 dp[i][j] 表示以下标i-1为结尾的字符串s&#xff0c;和以下标j-1为结尾的字符串t&#xff0c;相同子序列的长度为dp…

靠谱的动漫绘画培训班国内有哪些

动漫绘画培训班有哪些&#xff0c;今天给大家带来的是国内专业的动漫培训机构排名&#xff0c;这5个动漫培训机构&#xff0c;相信你一定都知道&#xff0c;快来看看吧&#xff01; 一&#xff1a;动漫绘画培训机构排名 1、轻微课 轻微课是国内人气很高的板绘学习平台&#…

2.23作业ccc

检测中断到来时&#xff0c;让LED灯状态取反&#xff0c;并且在串口工具上打印一句话例如&#xff1a;当按键1按下之后&#xff0c;让LED1状态取反&#xff0c;并打印“LED1 down”当按键2按下之后&#xff0c;让LED2状态取反&#xff0c;并打印“LED2 down”当按键3按下之后&a…

vue2安装ant-design UI报错 ERR! peer vue@“>=3.2.0“ from ant-design-vue@3.2.15

npm install ant-design-vue --save 安装报错&#xff0c;使用的是vue2&#xff0c;如图&#xff0c; npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: default0.1.0 npm ERR! Found: vue2.7.14 npm ERR! v…

13.Jenkins集成sonarqube

Jenkins集成sonarqube1.jenkins集成sonarqube2.jenkins以maven的方式集成sonarqube scanner报错1报错21.jenkins集成sonarqube 1.在jenkins插件管理中安装sonarqube scanner 2.jenkins要知道sonarqube服务端是谁&#xff0c;需要配置&#xff08;系统管理–系统配置–sonarq…

Knife4j文档请求异常错误

一、问题描述 springboot项目配置Knife4j后&#xff0c;访问地址http://xxxx/doc.html出现错误&#xff1a;Knife4j文档请求异常错误。 二、解决问题 使用google浏览器F12查看控制台后&#xff0c;发现有错误提示&#xff1a; 大致意思是某部分字段不能被有效解析为json。在…

因果推断方法(一)合成控制

知道的跳过下面的简单介绍&#xff1a; 就是比如广告主投放了10w元&#xff0c;那么他的收益怎么算&#xff1f;哪些订单就是广告带来的&#xff0c;哪些是不放广告也会购买&#xff1f; 合成控制法是目前我实际应用发现最好用的。置信度高&#xff0c;且容易理解。 简单讲下思…

iOS_苹果内购详细步骤

iOS苹果内购详细步骤iOS开发支付的两种方式1 Apple Pay 调取外部支付&#xff0c;例如支付宝、微信、银联等2 苹果内购IAP&#xff08;In-App Purchase&#xff09;1 IAP规则详解1.1 适用范围1.2 IAP类型1.2.1 Consumable products &#xff08;消耗型商品&#xff09;1.2.2 N…

python和C++代码实现图片九宫格切图程序(附VS2015配置Opencv教程)

1、python代码实现图片分割成九宫格 需要包含的库&#xff0c;没有下载安装的&#xff0c;需要自己安装哦。 实现原理很简单&#xff0c;就是用PIL库不断画小区域&#xff0c;切下来存储成新的小图片。 假设每一个格子的宽和高分别是w、h&#xff0c;那么第row行&#xff08…

【Maching Learning】深度学习常用评价指标(分类+回归)

深度学习分类、回归问题评价指标一、分类评价指标1.1混淆矩阵1.2准确率&#xff08;Accuracy&#xff09;1.3精确率&#xff08;Precision&#xff09;1.4召回率&#xff08;Recall&#xff09;1.5 F1{F}_{1}F1​分数&#xff08;F-Score&#xff0c;调和平均&#xff09;和 Fβ…

vue实现预览、下载和打印后端返回的pdf文件流

需求&#xff1a;后端返回pdf文件流&#xff0c;前端能够预览、下载打印。 后端返回的文件流部分截图 需要实现的效果图 前面第1步只是为了展示后台返回数据流&#xff0c;完成功能的时候&#xff0c;不需要调用接口的&#xff0c;只需要利用调用接口的url。 实现步骤&am…

Aspose.Imaging for .NET V23

Aspose.Imaging for .NET V23 Aspose.Imaging for.NET是帮助开发人员在自己的应用程序中创建、编辑、绘制或转换图像的类库。它包括在不安装Photoshop或任何其他图像编辑器的情况下以Adobe Photoshop原生格式保存的功能。Aspose.Imaging for.NET是一个灵活稳定的API&#xff0c…

frp内网穿透容器化快速部署

关于frp frp可以作为一个流量代理代发&#xff0c;可以将公网的流量转发到内网访问&#xff0c;从而实现访问公网即可访问到内网。 使用例子&#xff1a;两个不同局域网之间ssh访问 GitHub官网见&#xff1a;frp 详细使用见&#xff1a;frp详细使用 机器选择 为便于快速部署…

(考研湖科大教书匠计算机网络)第六章应用层-第六节:电子邮件

获取pdf&#xff1a;密码7281专栏目录首页&#xff1a;【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一&#xff1a;电子邮件&#xff08;1&#xff09;概述&#xff08;2&#xff09;举例二&#xff1a;简单邮件传送协议SMTP&#xff08;1&#xff09;SMTP基本工作…

震撼!阿里首次开源 Java 10万字题库,Github仅一天星标就超60K

程序员面试 现在是程序员找工作、跳槽最重要的月份。随着行业的发展程序员面试也越来越难&#xff0c;面试中都是7分的能力&#xff0c;再加上3分的技巧&#xff1b; 对于应聘者&#xff0c;重中之重的就是简历&#xff0c;面试前一定要将最拿手和最能吸引面试官的技能在简历…

Liunx常用命令行

Liunx常用命令行大全文件与目录创建删除mkdir命令rm命令touch命令跳转查看cd命令ls命令文本编辑工具VIM进程展示正在运行进程进程管理文件与目录 创建删除 mkdir命令 mkdir weiweiPractice&#xff1a;创建weiweiPractice目录 rm命令 rm -r weiweiPractice&#xff1a;删除…

【Leedcode】数据结构中链表必备的面试题(第三期)

【Leedcode】数据结构中链表必备的面试题&#xff08;第三期&#xff09; 文章目录【Leedcode】数据结构中链表必备的面试题&#xff08;第三期&#xff09;一、第一题1.题目2.思路3.源代码二、第二题1.题目2.思路(1)第一种情况&#xff1a;偶数个链表(2)第二种情况&#xff1a…

达梦数据库 闪回查询

当用户操作不慎导致错误的删改数据时&#xff0c;非常希望有一种简单快捷的方式可以恢复数据。闪回技术&#xff0c;就是为了用户可以迅速处理这种数据逻辑损坏的情况而产生的。 闪回技术主要是通过回滚段存储的 UNDO 记录来完成历史记录的还原。如果提交了&#xff0c;还没有…

钉钉微应用 - - - - 如何本地开发调试

关于钉钉微应用开发&#xff0c;真的尝尽了苦头。 要么是因为非钉钉环境报错&#xff0c;要么是发版到钉钉之后看不到日志的难受。 之前写过一个钉钉微应用 - - - - 如何本地开发调试&#xff1f;算是解决了一部分问题&#xff0c;但还是很不方便。 最近才发现&#xff0c;钉…

编写NodeJs脚本实现接口请求

要编写运行脚本,需要先搭建开发环境 环境搭建 nodeJs脚本运行,当然需要先安装nodejs环境 官方地址在这里: nodejs官网 打开官网地址,可以看到下面一句话: Node.js is an open-source, cross-platform JavaScript runtime environment. 在打开的页面,可以直接下载最新的…