The current repo belongs to Paused status, and some functions are restricted. For details, please refer to the description of repo status
8 Star 42 Fork 27

江节胜 / Java生产环境下性能监控与调优详解
Paused

Create your Gitee Account
Explore and code with more than 12 million developers,Free private repositories !:)
Sign up
This repository doesn't specify license. Please pay attention to the specific project description and its upstream code dependency when using it.
Clone or Download
1.7-详细笔记-Java代码成优化(借助字节码分析问题).md 5.56 KB
Copy Edit Raw Blame History
jiangjiesheng authored 2019-05-19 17:42 . 修改域名

7、Java代码层优化(借助字节码分析问题)

7.1 jvm字节码指令与javap

javap -help
用法: javap <options> <classes>
其中, 可能的选项包括:
  -help  --help  -?        输出此用法消息
  -version                 版本信息
  -v  -verbose             输出附加信息
  -l                       输出行号和本地变量表
  -public                  仅显示公共类和成员
  -protected               显示受保护的/公共类和成员
  -package                 显示程序包/受保护的/公共类
                           和成员 (默认)
  -p  -private             显示所有类和成员
  -c                       对代码进行反汇编
  -s                       输出内部类型签名
  -sysinfo                 显示正在处理的类的
                           系统信息 (路径, 大小, 日期, MD5 散列)
  -constants               显示最终常量
  -classpath <path>        指定查找用户类文件的位置
  -cp <path>               指定查找用户类文件的位置
  -bootclasspath <path>    覆盖引导类文件的位置

代码在 com.jiangjiesheng.javaOptimizationAndDebug.javacode.bytecode.ToGenerateByteCode.java

选中ToGenerateByteCode.java,执行Build > Compile 'ToGenerateByteCode.java' ,找到class文件:\target\classes\com\jiangjiesheng\javaOptimizationAndDebug\javacode\bytecode

打开cmd命令行

javap -verbose ToGenerateByteCode.class > ToGenerateByteCode.class.txt 

#生产的文件在 export/7th-javacode/ToGenerateByteCode.class.txt

7.2 基于栈的架构

avatar

相关文档 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html

7.3 i++与++i

代码在 com.jiangjiesheng.javaOptimizationAndDebug.javacode.SelfAdd.java

avatar

小结论:

  • java中i++与++i的效率应该没有区别。

7.4 字符串拼接+

代码在 com.jiangjiesheng.javaOptimizationAndDebug.javacode.StringAdd.java

注意每次拼接都是都会new一个StringBuilder

7.5 Try-Finally

public static String f1() {
	String str = "hello";
    try{
        return str;
    }
    finally{
        str = "imooc";
    }
}

System.out.println(f1()); // 打印 "hello"

更多参考 《已备份-JAVA-专题-try catch finally-执行顺序的验证说明》

7.6 String Constant Varialbe

代码在 com.jiangjiesheng.javaOptimizationAndDebug.javacode.Constant.java

com.jiangjiesheng.javaOptimizationAndDebug.javacode.StringConstant.java

final关键字在编译成字节码时会与优化

7.6 常用代码优化方法

  1. 尽量重用对象,不要循环创建对象,比如for循环字符串拼接

  2. 容器类初始化的时候指定长度:

List<String> collection = new ArrayList<String>(5);
Map<String, String>map = new HashMap<String, String>(32);
  1. ArrayList随机遍历快,LinkedList(双向链表)添加删除快

  2. 集合遍历尽量减少重复计算

for(int i=0,len=collection.size();i<len;i++) {}
  1. 使用Entry遍历Map
for (Map.Entry<String, String> entry : map.entrySet()) {
        String key = entry.getKey();
        String value = entry.getValue();
}
  1. 大数组复制用System.arraycopy()

  2. 尽量使用基本类型而不是包装类型

Integer i1 = 100;
Integer i2 = 100;
System.out.println(i1 == i2); // true 
Integer i3 = 1000;
Integer i4 = 1000;
System.out.println(i3 == i4);// false 

# Integer.IntegerCache中定义的缓存高位为127,超过这个数,就会new Integer。
  1. 不要手动调用System.gc()

  2. 及时消除过期对象的引用,防止内存泄漏

代码在 com.jiangjiesheng.javaOptimizationAndDebug.javacode.Stack.java

  1. 尽量使用局部变量,减小变量的作用域

  2. 尽量使用非同步的容器ArrayList VS Vector

Vector的很多方法加上synchronized,速度慢,线程安全。

  1. 尽量减小同步的作用范围,synchronized方法 VS 代码块

  2. ThreadLocal缓存线程不安全的对象,SimpleDateFormat

  3. 尽量使用延迟加载

单例模式 参考《JAVA-线程安全的单例模式》

public class Singleton {//synchronized代码块锁+双重检查
  private static volatile Singleton instance = null;
  private Singleton() {
  }
  public static Singleton getInstance() {
      if (null == instance) {
          synchronized (Singleton.class) {
              if (null == instance) { //1
                  instance = new Singleton();
              }
          }
      }
      return instance;
  }

}

// valotile作用:内存可见性、禁止指令重排序
// 结论:线程安全、绝对单例
  1. 尽量减少使用反射,加缓存

  2. 尽量使用连接池、线程池、对象池、缓存

  3. 及时释放资源,I/O流、Socket、数据库连接

  4. 慎用异常,不要用抛异常来表示正常的业务逻辑

  5. String操作尽量少用正则表达式

replace、replaceAll、split

  1. 日志输出注意使用不同的级别

  2. 日志中参数拼接使用占位符

log.info("orderId:" + orderId); //不推荐 有拼接
log.info("orderId:{}",orderId); //推荐 

个人网站 tech.jiangjiesheng.cn

QQ:596957738

微信:596957738

EMail: dev@jiangjiesheng.cn

Java
1
https://gitee.com/jiangjiesheng/java-optimization-and-debug-for-prod-env.git
git@gitee.com:jiangjiesheng/java-optimization-and-debug-for-prod-env.git
jiangjiesheng
java-optimization-and-debug-for-prod-env
Java生产环境下性能监控与调优详解
master

Search