有那些猎头做单的网站,太原晋民网站建设公司,下载app至手机,遵义网站0、问题代码#xff1a;
代码问题其实很明显#xff0c;但是这里主要是为了练习如何使用工具进行分析 所以最好先不要看代码#xff0c;假装不知道程序逻辑#xff0c;而是先通过工具去分析#xff0c;再结合分析数据去看代码#xff0c;从而推出问题点在哪
import jav…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) {ListString list new ArrayList();String str index;for (int j 0; j 10000; j) {str aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaj;}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) {ListString list new ArrayList();StringBuilder str new StringBuilder(50*10000);str.append(index);for (int j 0; j 10000; j) {str.append(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaj);}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占用高的线程结合阅读代码进行分析了