类加载过程

发布时间:2023年12月17日

**

类加载过程

**
在这里插入图片描述
加载:

  • 读取类的二进制流
  • 转为方法区数据结构,并存放到方法区
  • 在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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。