前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java 调优概要

java 调优概要

作者头像
birdskyws
发布2019-02-25 11:09:26
7000
发布2019-02-25 11:09:26
举报

Java调优

实际问题

  • CPU彪高如何处理?
  • 生产环境应该给应用分配多少线程合适?
  • 不加log如何确定请求是否执行了某一行代码?
  • 不加log如何实时查看某个方法的入参与返回值?
  • JVM的字节码是什么东西?
  • 循环体中做字符串+拼接为什么效率低?
  • 字符串+拼接一定就是StringBuilder.append吗?
  • String常量池是咋回事?
  • i++与++i到底哪种写法效率高?

主要内容

工具
  • 熟练使用各种监控工具和调试工具
  • 从容应对生成环境在遇到的各种调试和性能问题
  • 熟练JVM的字节码指令
  • 深入理解JVM的自动内存回收机制,学会GC调优
基于JDK命令行
  • JVisualVM的可视化
  • Btrace的监控调试
  • tomcat,nginx,jvm GC调优,java代码
  • JVM参数jinfo,jstat统计信息
图形化工具
  • jmap+MAT
  • jstack线程情况
  • Btrace安装与使用
Tomcat工具
  • tomcat 远程debug
  • psi-probe和Tomcat-manager监控Tomcat
  • Tomcat调优
Nginx工具
  • Nginx性能监控与调优
  • ngx_http_stub_status监控连接信息
  • ngxtop监控请求信息、nginx-rdd图形监控
JVM内存结构
  • 垃圾回收算法、垃圾回收器
  • GC日志格式与可视化日志分析工具
  • Tomcat的Gc调优实战
Java代码层调优
  • JVM字节码指令与Javap
  • i++,++i,字符串拼接
  • 常用代码优化方法

一、JDK命令行工具的监控

1.1 主要内容
  • jvm参数类型
  • 运行时JVM参数参看
  • jstat查看虚拟机统计信息
  • jmap+MAT实战内存溢出
  • jstack 实战死锁
1.2 JVM参数类型
  • 标准参数
  • X参数
  • XX参数
标准参数
  • -help
  • -server -client
  • -version -showversion
  • -cp -classpath
X参数
  • -Xint 解释执行
  • -Xcomp 第一次使用就编译成本地代码
  • -Xmixed 混合模式,JVM自己来决定是否编译成本地代码
XX参数分类

分为两类,一种是boolean类型,设置生效不生效,另一类是设置值。-XX:<name>=<value>

  • -XX:+UseConcMarkSweepGC使用cms垃圾收集
  • -XX:+UseG1GC 使用G1垃圾回收
  • -XX:MaxGCPauseMillis=500
  • -Xms等价于-XX:InitialHeapSize: -Xmx设置;-Xms32M -Xmx2G
1.3查看JVM运行时参数
在命令运行时,添加参数,打印参数

-XX:+PrintFlagsInitial 初始值 -XX:+PrintFlagsFinal 最终值

查看正在运行的jVM

jinfo -flags pid,打印手动赋过值得 jinfo -flag 参数名称 pid,查看进程参数 jinfo -flag MaxHeapSize 23789

1.4 jstat查看JVM统计信息
  • 类加载信息
  • 垃圾回收信息,重点。动态查看内存块
  • JIT编译信息
代码语言:javascript
复制
jstat -<option> pid   
-class 类加载信息
-compiler 编译信息
-gc 垃圾回收信息
-printcompilation
  • 查看类加载信息,1000ms,10打印次数
代码语言:javascript
复制
[root@localhost home]# jstat -class 11359 1000 10
Loaded  Bytes  Unloaded  Bytes     Time
  6654 12119.4       32    44.8       6.07
  6654 12119.4       32    44.8       6.07
  6654 12119.4       32    44.8       6.07
  • 查看GC信息
代码语言:javascript
复制
[root@localhost home]# jstat -gc 11359 1000 10
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU        YGC     YGCT    FGC    FGCT     GCT
1088.0 1088.0 272.1   0.0    8704.0   3000.8   21888.0    14094.7   36096.0 34306.6 4864.0 4425.1     52    0.163   2      0.076    0.239
1088.0 1088.0 272.1   0.0    8704.0   3000.8   21888.0    14094.7   36096.0 34306.6 4864.0 4425.1     52    0.163   2      0.076    0.239
1088.0 1088.0 272.1   0.0    8704.0   3000.8   21888.0    14094.7   36096.0 34306.6 4864.0 4425.1     52    0.163   2      0.076    0.239
1088.0 1088.0 272.1   0.0    8704.0   3000.8   21888.0    14094.7   36096.0 34306.6 4864.0 4425.1     52    0.163   2      0.076    0.239

jstat -gc参数

1.5构建溢出
构建堆溢出
代码语言:javascript
复制
    List<User> userList = new ArrayList();
    /**
     * -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home
     * java.lang.OutOfMemoryError: Java heap space
     * Dumping heap to /home/java_pid10107.hprof ...
     * Heap dump file created [48133870 bytes in 0.202 secs]
     * Exception in thread "http-nio-8080-exec-1" java.lang.OutOfMemoryError: Java heap space
     * @return
     */
    @GetMapping("/heap")
    public String heap()
    {
        int i=0;
        while(true)
        {
            userList.add(new User(UUID.randomUUID().toString(),i++));
        }
    }
构建非堆溢出
代码语言:javascript
复制
    List<Class<?>> classList = new ArrayList<Class<?>>();
    @GetMapping("/noheap")
    public String noheap()
    {
        classList.addAll(Metaspace.createClasses());
        return "noheap";
    }
代码语言:javascript
复制
/*
 * https://blog.csdn.net/bolg_hero/article/details/78189621
 * 继承ClassLoader是为了方便调用defineClass方法,因为该方法的定义为protected
 * */
public class Metaspace extends ClassLoader {

    public static List<Class<?>> createClasses() {
        // 类持有
        List<Class<?>> classes = new ArrayList<Class<?>>();
        // 循环1000w次生成1000w个不同的类。
        for (int i = 0; i < 10000000; ++i) {
            ClassWriter cw = new ClassWriter(0);
            // 定义一个类名称为Class{i},它的访问域为public,父类为java.lang.Object,不实现任何接口
            cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, "Class" + i, null,
                    "java/lang/Object", null);
            // 定义构造函数<init>方法
            MethodVisitor mw = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
                    "()V", null, null);
            // 第一个指令为加载this
            mw.visitVarInsn(Opcodes.ALOAD, 0);
            // 第二个指令为调用父类Object的构造函数
            mw.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object",
                    "<init>", "()V");
            // 第三条指令为return
            mw.visitInsn(Opcodes.RETURN);
            mw.visitMaxs(1, 1);
            mw.visitEnd();
            Metaspace test = new Metaspace();
            byte[] code = cw.toByteArray();
            // 定义类
            Class<?> exampleClass = test.defineClass("Class" + i, code, 0, code.length);
            classes.add(exampleClass);
        }
        return classes;
    }
}
1.6 导出内存镜像文件
  • 内存溢出是自动导出,将下面的参数设置添加到命令当中
代码语言:javascript
复制
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./
  • 用JMap导出当前进程的内存镜像 heap.hprof是导出内存镜像的文件名 live参数导出存活对象
代码语言:javascript
复制
jmap -dump:live,format=b,file=heap.hprof pid
1.7 jmap命令行
代码语言:javascript
复制
> jmap -heap pid
[root@localhost home]# jmap -heap 11359
Attaching to process ID 11359, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.191-b12

using thread-local object allocation.
Mark Sweep Compact GC

Heap Configuration:
   MinHeapFreeRatio         = 40
   MaxHeapFreeRatio         = 70
   MaxHeapSize              = 33554432 (32.0MB)
   NewSize                  = 11141120 (10.625MB)
   MaxNewSize               = 11141120 (10.625MB)
   OldSize                  = 22413312 (21.375MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
New Generation (Eden + 1 Survivor Space):
   capacity = 10027008 (9.5625MB)
   used     = 4085912 (3.8966293334960938MB)
   free     = 5941096 (5.665870666503906MB)
   40.749064925449346% used
Eden Space:
   capacity = 8912896 (8.5MB)
   used     = 3807328 (3.630950927734375MB)
   free     = 5105568 (4.869049072265625MB)
   42.71706973805147% used
From Space:
   capacity = 1114112 (1.0625MB)
   used     = 278584 (0.26567840576171875MB)
   free     = 835528 (0.7968215942382812MB)
   25.00502642463235% used
To Space:
   capacity = 1114112 (1.0625MB)
   used     = 0 (0.0MB)
   free     = 1114112 (1.0625MB)
   0.0% used
tenured generation:
   capacity = 22413312 (21.375MB)
   used     = 14432968 (13.764350891113281MB)
   free     = 7980344 (7.610649108886719MB)
   64.39462405199195% used

13278 interned Strings occupying 1888808 bytes.
[root@localhost home]#
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.12.11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Java调优
    • 实际问题
      • 主要内容
        • 一、JDK命令行工具的监控
        相关产品与服务
        命令行工具
        腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档