首页 > 基础资料 博客日记
几分钟了解下java虚拟机--02
2025-06-18 00:00:02基础资料围观8次
这篇文章介绍了几分钟了解下java虚拟机--02,分享给大家做个参考,收藏Java资料网收获更多编程知识
几分钟应该看不完,私密马赛, 俺是标题党
既然来了, 看看吧, 球球你了
Java类加载器
类的生命周期和加载过程
- 加载 加载所有的.class文件/jar文件/网络流 →字节流 (JVM 与java.lang.classLoader协作)
存储于Metaspace/Method Area
- 校验 确保 class 文件里的字节流信息符合当前虚拟机的要求,不会危害虚拟机的安全
- 准备 设置变量默认值 分配内存
- 解析 解析常量池符号引用转换为直接引用,主要有以下四种:类或接口的解析、字段解析、类方法解析、接口方法解析 链接相关参数, 方法索引(为后续初始化和运行提供直接引用)
- 初始化 执行类构造器
<clinit>
方法 初始化
类加载时机
类加载机制
JVM方法调用
方法于JVM构成 : 类名, 方法名, 方法描述符{参数类型, 返回参数类型}
JVM方法查询
子类的静态方法会隐藏(注意与重写区分)父类中的同名、同描述符的静态方法 Interface 同理
虚方法调用
- 虚拟方法表 链接时建立class的虚方法(非static, final)表
分离invokinterface
与invokevirtual
原因
class A
1: method1
2: method2
class B extends A
1: method1
2: method2
3: method3
class B extends A implements X
1: method1
2: method2
3: method3
4: methodX
class C implements X
1: methodC
2: methodX
-
内联缓存
*-只是缓存并非内联(嵌入内部)*
执行过程中,如果碰到已缓存的类型,内联缓存便会直接调用该类型所对应的目标方法。
- 劣化为超多态状态
JVM处理异常
异常基本概念
因为异常总是动态的, 实时的, 所以我们总是new exception()
如何捕获异常
每个method都会维护一张 Exception table
Exception table:
from to target type
0 3 6 Class java/lang/Exception
Java 7 的 Suppressed 异常以及语法糖
try {
in0 = new FileInputStream(new File("in0.txt"));
...
try {
in1 = new FileInputStream(new File("in1.txt"));
...
try {
in2 = new FileInputStream(new File("in2.txt"));
...
} finally {
if (in2 != null) in2.close();
}
} finally {
if (in1 != null) in1.close();
}
} finally {
if (in0 != null) in0.close();
try (Foo foo0 = new Foo("Foo0"); // try-with-resources语法糖优化后
Foo foo1 = new Foo("Foo1"); // 该语法糖下自动使用suppressed异常
Foo foo2 = new Foo("Foo2")) {
throw new RuntimeException("Initial");
}
**suppressed异常**允许将一个异常附于另一个异常之上。因此,抛出的异常可以附带多个异常的信息
JVM实现反射机制
依赖于 JVM 的类加载器和运行时数据结构(如方法表、字段表)
怎么用
应用
- IDE 每当我们敲入点号时,IDE 便会根据点号前的内容,动态展示可以访问的字段或者方法
- Java调试器 在调试过程中枚举某一对象所有字段的值
- Spring framework IOC
Method.invoke
本地实现, 委派实现, 动态实现(均由MethodAccessor
抽象)
getMethod会形成一份class内方法的的拷贝 -避免在热点代码中使用getMethod
取消委派实现, 关闭检查时目标方法的权限可以小幅度提升性能
public final class Method extends Executable {
...
public Object invoke(Object obj, Object... args) throws ... {
... // 权限检查
MethodAccessor ma = methodAccessor;
if (ma == null) {
ma = acquireMethodAccessor();
}
return ma.invoke(obj, args);
}
}
- 本地实现
// v0 版本
import java.lang.reflect.Method;
public class Test {
public static void target(int i) {
new Exception("#" + i).printStackTrace();
}
public static void main(String[] args) throws Exception {
Class<?> klass = Class.forName("Test");
Method method = klass.getMethod("target", int.class);
method.invoke(null, 0);
}
}
# 不同版本的输出略有不同,这里我使用了 Java 10。
$ java Test
java.lang.Exception: #0
at Test.target(Test.java:5)
**本地实现** at java.base/jdk.internal.reflect.NativeMethodAccessorImpl .invoke0(Native Method)
**↑** at java.base/jdk.internal.reflect.NativeMethodAccessorImpl. .invoke(NativeMethodAccessorImpl.java:62)
**委派实现** at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.i .invoke(DelegatingMethodAccessorImpl.java:43)
**↑
invoke** at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at Test.main(Test.java:131
- 委派实现
作为invoke实现的中间件
选择method invoke本地实现还是动态实现
- 动态实现(纯java字节码, 无需重新从java→c++→java)
优势在于避免了 JNI ( java native interface )的切换开销,但它的缺点是生成字节码耗时
// 动态实现的伪代码,这里只列举了关键的调用逻辑,其实它还包括调用者检测、参数检测的字节码。
package jdk.internal.reflect;
public class GeneratedMethodAccessor1 extends ... {
@Overrides
public Object invoke(Object obj, Object[] args) throws ... {
Test.target((int) args[0]);
return null;
}
}
Method method1 = Test.class.getMethod("target", int.class);
Method method2 = Test.class.getMethod("target", int.class);
JVM实现invokedynamic
方法句柄(Method Handle)
class Foo {
private static void bar(Object o) {
..
}
public static Lookup lookup() {
return MethodHandles.lookup();
}
}
// 获取方法句柄的不同方式
MethodHandles.Lookup l = Foo.lookup(); // 具备 Foo 类的访问权限
Method m = Foo.class.getDeclaredMethod("bar", Object.class);
MethodHandle mh0 = l.unreflect(m);
MethodType t = MethodType.methodType(void.class, Object.class);
MethodHandle mh1 = l.findStatic(Foo.class, "bar", t);
方法句柄的操作
如果你看完了, 非常感谢你对我付出的认可🥰🥰🥰😘😘😘
文章来源:https://www.cnblogs.com/many-bucket/p/18933753
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签: