类加载过程
2023-12-17 20:21:59
**
类加载过程
**
加载:
- 读取类的二进制流
- 转为方法区数据结构,并存放到方法区
- 在Java堆中产生java.lang.Class对象
验证:
- 作用: 验证class文件是不是符合规范
- 文件格式的验证(是否以0xCAFEBABE开头 、 版本号是否合理)
- 元数据验证(是否有父类、是否继承了final类、非抽象类实现了所有的抽象方法)
- 字节码验证:(运行检查、栈数据类型和操作吗操作参数吻合、跳转指令指向合理的位置)
- 符号引用验证:(常量池中描述类是否存在、访问的方法或字段是否存在且有足够的权限)
准备:
- 作用:为类的静态变量分配内存, 初始化为系统的初始值
- fianl static 修饰的变量:直接复制为用户定义的值,比如private final static in value = 123 , 直接赋值123
- private static int value = 123 , 该阶段的值依然是0
解析:
- 作用:符号引用转换成直接引用
字节码是如何运行的?
- 解释执行:有解释器一行一行翻译执行
- 编译执行:把字节码编译成机器码,直接执行机器码
解释 vs 编译
解释执行:
- 优势在于没有编译的等待时间
- 性能相对差一些
编译执行:
- 运行效率会高很多, 一般认为比解释执行快一个数量级
- 带来了额外的开销 (内存开销、cpu开销)
如何找到热点代码
-
基于采样的热点探测 (周期的检测各个线程的栈底是不是会出现同一个方法)
-
基于计数器的热点探测 (为每个方法或者是代码块设置计数器 , 统计计数器的值是否达到阈值)
-
Hotsort采用的是基于计数器的热点探测
热点方法的内联
- 把目标方法的代码复制到发起调用的方法之中,避免发生真实的方法调用
方法内联的条件一:
- 方法体足够小
方法内联的条件二:
- 被调用方法运行时的实现被可以唯一确定
- static、private方法以及final方法,JIT可以唯一确定具体的实现代码
- public的实例方法,指向的实现可能是自身、父类、子类的代码,当且仅当JIT能够唯一确定方法的具体实现时 , 才有可能完成内联。
方法内联的注意点:
- 尽量让方法体小一些
- 尽量使用final、private、static关键字修饰方法,避免因为多态,需要对方法做额外的检查
- 一些场景下,可通过JVM参数修改阈值,从而让更多方法内联。
文章来源:https://blog.csdn.net/weixin_43538215/article/details/135047021
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!