JVM常见问题总结

  1. JVM内存结构布局
    JVM内存主要分为:本地方法栈、虚拟机栈、程序计数器、堆、方法区、元空间
  • 堆(参考7. Java内存回收机制)
    OOM故障发源地,存放着几乎所有的实例对象,由GC自动进行垃圾回收,线程间资源共享,可以通过参数进行手动调节。但是线上环境应将-Xms和-Xmx设置成相等的值,避免堆空间频繁缩容与扩容带来的性能损耗。堆内存模型
    堆内存模型
  • 元空间
    Java8之后使用元空间替换原来的永久代。字符串常量移至堆内存,元空间存放的信息包括:类结构信息、字段、静态属性、方法、常量等
  • 虚拟机栈(栈)-线程私有
    用于支持jvm进行方法调用。只有栈顶的栈帧才是有效的。栈帧结构如下:
    栈帧结构
    (1)局部变量表:存放方法参数和局部变量的区域,该区域中的局部变量必须显式初始化,对于实例方法而言,index[0]位置上存放的是方法所属实例的引用,然后才是方法参数和局部变量,STORE命令是将操作栈运算完成的局部变量存储到局部变量表
    (2)操作栈:JVM执行引擎依赖操作栈,也就是所谓的JVM执行引擎是基于栈的执行引擎。
    (3)动态链接:指的是常量池中对当前方法的引用,以支持方法调用过程中的动态链接
    (4)方法返回地址:指的是方法当前被调用的位置,有三种情况:
    I:方法将返回值压入上层调用栈帧
    II:异常信息抛给能够处理的栈帧
    III:程序计数器指向方法调用后的下一条指令
  • 本地方法栈 - 线程私有
    调用的本地方法会压入改栈
  • 程序计数器
    存放指令执行的偏移量和行号指示器等信息
  1. JVM字节码
    Java实现跨平台的基础就是字节码(.class文件),首先jvm会将Java文件编译成字节码文件,从而利用字节码文件实现一次编译到处执行。JVM执行代码的主要方式是解释执行,另外对于热点代码,会将字节码编译成二进制机器码执行。二进制文件起始位置有一个使用十六进制编码的cafe babe,该数据标志一个Java文件,如果没有,那么就不是Java文件或者文件已损坏

  2. 字节码主要指令

  • 加载或存储指令
    (1)将局部变量加载到操作栈,如ILOAD(表示将int类型数据加载到操作栈),ALOAD(将引用类型的局部变量加载到操作栈,‘A’表示是引用类型变量)
    (2)将操作栈顶存储到局部变量表,如ISTORE、ASTORE等
    (3)将常量加载到操作栈顶,这一操作的频度较高
    • ICONST:加载-1~5的数
    • BIPUSH:加载-128-127的数(byte表示范围)
    • SIPUSH:加载-32768-32767的数(short表示范围)
    • LDC:-2147483648-2147483647或者字符串使用该指令
  • 运算指令:对两个数进行运算操作
    (1)IADD:执行加法操作
    (2)IMUL:执行乘法操作
  • 类型转换命令:显式转换数据类型
    (1)I2L:int转换成long
    (2)D2F:double转换成float
  • 对象创建于访问指令
    (1)对象创建指令:NEW、NEWARRAY等
    (2)访问属性指令:GETFIELD、PUTFIELD、GETSTATIC等
    (3)检查实力类型:CONSTANCEOF、CHECKCAST
  • 操作栈管理指令
    (1)弹出栈顶元素操作:POP(弹出一个元素),POP2(弹出两个元素)
    (2)复制栈顶元素并压入栈:DUP
  • 方法调用与返回指令
    (1)调用对象的实例方法:INVOKEVIRTUAL
    (2)调用实例初始化方法、私有方法及父类方法等:INVOKESPECIAL
    (3)调用类静态方法:INVOKESTATIC
    (4)返回VOID类型:RETURN
  • 同步指令
    (1)使用ACC_SYNCHRONIZED标志同步方法
  1. 将源码转换成字节码要经历哪些过程?
    源文件 -》词法分析 -》语法分析 -》语义分析 -》生成字节码
    词法分析:是将源文件按照空格进行分割出不同含义的单词,组成token信息流传递给语法分析器
    语法分析:是将上一步的数据按照Java语法格式解析成语法树
    语义分析:会完成关键字的使用是否正确、类型是否匹配、作用域是否正确等进行分析,分析无误后就会生成对应的字节码

  2. 类加载过程

  • 类的加载过程称作“双亲委派加载模型”,或者说是“溯源委派加载模型”
    类加载器在启动时会完成三个主要的工作:加载、链接、初始化
    加载:读取类文件,检测cafebabe、常量、文件长度、有无父类等情况,然后创建对应的java.lang.Class类
    链接:包括验证、准备、解析三个步骤。验证过程会比加载过程更加细致,比如进行关键字使用是否有无的检查,类型是否使用正确的检查等;准备阶段是为静态变量分配内存并设置初始值;解析过程是为了确保各个类之间引用关系的正确性,完成内存结构布局
    初始化:执行类构造器方法完成类初始化工作

  • 类加载器等级关系
    I:Bootstrap Classsloader -> jvm启动时创建,加载核心Java类
    II: Plantform Classloader(Java9,之前叫做Extension Classloader)-> 加载拓展系统类
    III:Application Classloader -> 加载用户定义的CLASSPATH下的类
    IV:User Classloader -> 用户自定义类加载器

  1. 对象创建的过程
    (1)检查类元信息是否存在
    (2)分配对象内存
    (3)设定成员变量默认值
    (4)设置对象头,比如对象hash值,所属类元信息等
    (5)执行初始化方法

  2. JVM垃圾回收机制
    堆内存模型
    对象刚创建时会存放到Eden区,当Eden区空间已满时,会触发YGC;old区会存放Young区存活下来的对象和Young区存放不下的超大对象
    一个关键概念GC Roots:如果一个对象与GC Roots没有直接或间接的联系时,就是可以被回收的对象。可作为GC Roots的对象主要有以下几种:类静态变量引用的对象、常量引用的对象、虚拟机栈中引用的对象、本地方法栈中引用的对象等

  • GC基础算法:“标记-清除算法”
    从GC Roots开始,标记有引用关系的对象,最后将没有标记的对象删除
  • 标记-清除算法改进 -》标记-整理算法
    S0和S1区域的作用
    首先将当前可用区域(假设为S0)中有引用的对象全部复制到另一个区域(S1),然后将S0区域全部清除,将S1区域设置为当前可用区域,如此过程往复

by Relon 文章如有问题请指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值