JVM进阶 -- 浅谈即时编译 发表于 2019-01-02 | 分类于 Java , JVM , Advanced | 阅读次数: | 本文字数: 6.4k | 阅读时长 ≈ 12 分钟 概念 即时编译是用来提升应用运行效率的技术 代码会先在JVM上解释执行,之后反复执行的热点代码会被即时翻译成为机器码,直接运行在底层硬件上 阅读全文 »
JVM基础 -- Java语法糖 发表于 2019-01-01 | 分类于 Java , JVM , Baisc | 阅读次数: | 本文字数: 4.8k | 阅读时长 ≈ 9 分钟 自动装拆箱Java代码12345public int foo() { List<Integer> list = new ArrayList<>(); list.add(0); return list.get(0);} 阅读全文 »
JVM基础 -- 浅谈synchronized 发表于 2018-12-31 | 分类于 Java , JVM , Baisc | 阅读次数: | 本文字数: 3.9k | 阅读时长 ≈ 7 分钟 抽象算法synchronized代码块12345public void foo(Object lock) { synchronized (lock) { lock.hashCode(); }} 阅读全文 »
JVM基础 -- Java内存模型 发表于 2018-12-30 | 分类于 Java , JVM , Baisc | 阅读次数: | 本文字数: 3k | 阅读时长 ≈ 5 分钟 JIT的重排序Java代码1234567891011121314public class JMM { private int a = 0; private int b = 0; public void method1() { int r2 = a; // A1 b = 1; // A2 } public void method2() { int r1 = b; // B1 a = 2; // B2 }} 单线程,method1->method2,(r1,r2)=(1,0) 单线程,method2->method1,(r1,r2)=(0,2) 多线程,没有重排序,A1->B1->A2->B2,(r1,r2)=(0,0) 多线程,重排序,A2->B1->B2->A1,(r1,r2)=(1,2) 阅读全文 »
JVM基础 -- 垃圾回收基础 发表于 2018-12-26 | 分类于 Java , JVM , Baisc | 阅读次数: | 本文字数: 3.6k | 阅读时长 ≈ 6 分钟 判定对象存亡垃圾回收标记的是非垃圾 引用计数法 为每个对象添加一个引用计数器,用来统计指向该对象的引用个数 如果有一个引用,被赋值为某一对象,那么将该对象的引用计数器+1 如果指向某一对象的引用,被赋值为其他值,那么该对象的引用计数器-1 一旦某个对象的引用计数器为0,说明对象已经死亡 缺点 额外的空间来存储计数器 + 繁琐的更新操作 无法处理循环引用的场景,造成内存泄露 阅读全文 »
JVM基础 -- Java对象的内存布局 发表于 2018-12-22 | 分类于 Java , JVM , Baisc | 阅读次数: | 本文字数: 4k | 阅读时长 ≈ 7 分钟 创建对象 new + 反射 通过调用构造器来初始化实例字段 Object.clone + 反序列化 通过直接复制已有的数据,来初始化新建对象的实例字段 Unsafe.allocateInstance 不会初始化实例字段 123456// Foo foo = new Foo();对应的字节码// new指令:请求内存0: new // class me/zhongmingmao/basic/jol/Foo3: dup// invokespecial指令:调用构造器4: invokespecial // Method "<init>":()V 阅读全文 »
JVM基础 -- 浅谈反射 发表于 2018-12-20 | 分类于 Java , JVM , Baisc | 阅读次数: | 本文字数: 11k | 阅读时长 ≈ 20 分钟 反射API获取Class对象 Class.forName() object.getClass() 类名.class Integer.TYPE指向int.class 数组类型:类名[].class 1public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int"); 阅读全文 »
JVM基础 -- 异常处理 发表于 2018-12-19 | 分类于 Java , JVM , Baisc | 阅读次数: | 本文字数: 5.6k | 阅读时长 ≈ 10 分钟 抛出异常 + 捕获异常抛出异常 显式抛异常的主体是应用程序,使用throw关键字 隐式抛异常的主体是JVM,在JVM执行过程中,碰到无法继续执行的异常状态时,自动抛出异常 例如ArrayIndexOutOfBoundsException 捕获异常 try代码块 标记需要异常监控的代码 catch代码块 定义了针对指定类型的异常处理器 多个catch代码块,JVM会从上至下匹配异常处理器 前面catch代码块所捕获的异常类型不能覆盖后边的,否则编译器会报错 finally代码块 声明一段必定运行的代码 程序正常执行,未抛出异常,try -> finally 程序抛出异常未被捕获,try(throw A) -> finally -> throw A 程序抛出异常并被捕获,try(throw A) -> catch(A) -> finally 程序抛出异常并被捕获,并且catch代码块也抛出异常,try(throw A) -> catch(A, throw B) -> finally -> throw B finally代码块抛出异常,中断finally代码块的执行,往外抛出异常 阅读全文 »
JVM基础 -- 桥接方法 发表于 2018-12-18 | 分类于 Java , JVM , Baisc | 阅读次数: | 本文字数: 5.3k | 阅读时长 ≈ 10 分钟 背景Java语言的重写与JVM的重写并不一致,当在Java语言中为重写而在JVM中为非重写,编译器会通过生成桥接方法来实现Java中的重写语义 桥接方法 – 返回类型Java代码1234567891011121314151617181920@Slf4jpublic class Father { public Number work() { return 1.0; } public static void main(String[] args) { Father father = new Son(); // 实际调用的是桥接方法 Number work = father.work(); log.info("{}", work); }}class Son extends Father { @Override public Double work() { return 2.0; }} 阅读全文 »
JVM基础 -- 方法调用 发表于 2018-12-17 | 分类于 Java , JVM , Baisc | 阅读次数: | 本文字数: 9.5k | 阅读时长 ≈ 17 分钟 重载+重写 重载:方法名相同,但方法描述符不相同的方法之间的关系 重写:方法名相同,并且方法描述符也相同的方法之间的关系 方法描述符 Java:参数类型 JVM:参数类型+返回类型 重载 重载的方法在编译过程即可完成识别 具体到在每个方法调用时,Java编译器会根据传入参数的声明类型(不是实际类型)来选取重载方法 三阶段 在不允许自动装拆箱和可变长参数的情况下,选取重载方法 允许自动装拆箱,但不允许可变长参数的情况下,选取重载方法 在允许自动装拆箱和可变长参数的情况下,选取重载方法 Java编译器在同一阶段找到多个适配的方法,依据形式参数的继承关系,选择最贴切的方法,原则:子类优先 重载来源 同一个类中定义 继承父类非私有同名方法 阅读全文 »