一个简单的JVM调优过程

JVM调优指的是对Java虚拟机(JVM)的配置和优化,以提高Java应用程序的性能和可伸缩性。JVM调优包括:堆内存配置、垃圾回收配置、线程配置、类加载配置、JIT编译器配置。

这里例句一个简单的实例,并从堆内存配置和垃圾回收配置来展开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 T15_FullGC_Problem01 {
    private static class CardInfo{
        BigDecimal price = new BigDecimal(0.0);
        String name="zhangsan";
        int age=5;
        Date birthdate=new Date();
        private 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->{
            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;
    }
}
  • 编译上述java源码为.class文件,然后输入如下命令运行该.class文件:
    java -Xms200M -Xmx200M -XX:+PrintGC T15_FullGC_Problem01

 (注:这里我在windows操做系统开发环境中编写的java源码,然后经过编译后再out文件夹下生成了该文件对应的class文件,最后将该class文件赋值到linux环境下运行。由于起初在window系统上的java版本为jdk11,而linux系统上的为jdk8,所以在linux上运行复制过来的class文件总是出现major version版本报错的问题)

  • 启动上述class文件后,会出现如下打印结果:

 这里展示了垃圾收集器处理过程中的一些信息和内存的分配和回收情况。

  • 使用jdk自带的命令分析上述java进程运行过程中出现的问题:
  1. jsp:用于查找当前内中运行了哪些java进行以及对应的进程号;
  2. jinfo pid:用于查看某个进程的详细信息;
  3. jstat pid:用于查看某个进程的状态;
  4. jstack pid:对某个进程进行堆栈跟踪;
  5. jmap:用于生成java进程当前内存内存转储快照,用于检查内存溢出或者内存泄露;(jmap -dump:live, format=b.file=[name],pid ->生成dump文件,然后可以使用jvisualvm进行图像化分析;jmap -heap pid:查看堆的详细信息;jmap -histo pid | head -n:生成某线程前n个重点关注的对象)
  •  jmap在进行java进程分析的时候,会出现如下问题:
  1. jmap在生成快照时会STW(stop the word);
  2. jmap在远程连接上不方便,需要具有相应的访问权限;

(解决jmap使用过程中出现的问题有:

  1. 开启HeapDumpOnOutOfMemoryError功能;
  2. 高可用方式调优;
  3. 压测环境下调优;(TCPCopy模拟真是环境下的访问量)

  •  Arthas:一个可以动态检测java运行状态并调优的工具:
  1. 安装:curl -O(大写的O) https:// arthas.aliyun.com/arthas-boot.jar
  2. 运行:java -jar arthas-boot.jar
  3. 选择需要动态检测的java线程
  4. 利用arthas中的各种分析命令进行分析(-help)

 这里介绍两个有用的arthas命令:

jad T15_FullGC_Problem01//用于class文件的反向编译,生成java源码
#反编译有什么意义吗?
#1、小公司小型项目的作用不是很大;
#2、大公司大型项目,反编译可以快速定位异常的位置并修改源码;
dashboard//监控仪盘

 (注:起初使用arthas检测T15_FullGC_Problem01这个进程时,出现了端口被占用的错误,即是打开T15_FullGC_Problem01这个进程时,进程本身所给的pid号被其他进程占用着。进过仔细检查,发现时以前运行hadoop集群时没有关闭导致的,并且此时再次执行hadoop关闭指令依旧无法清除像对应的进程,这是由于hadoop打开后的进程信息会保存到temp文件夹下,而temp文件夹下的文件会被定期清理,从而导致再次执行hadoop关闭指令时,指令无法找到对应的执行西信息,从而导致指令失效。解决办法:首先,使用Kill -9 -pid 强制杀死一个java进程;然后,重新设置pid信息的保存路径,使其可以长期保存) 

  •  查看所有与JVM设置相关的参数的方法:
    java -XX:+PrintFlagFinal;//查看所有JVM参数启动的初始值;
    java -XX:+PrintCommandLineFlag;//查看哪些已经被用户或者java设置过的详细XX参数;

猜你喜欢

转载自blog.csdn.net/weixin_45158611/article/details/129805353