• 【JVM】运行时数据区总结(十一)


    运行时举例

      图解示例

    • 代码
      1 public class RuntimeDemo {
      2     public static void main(String[] args) {
      3         int x = 500;
      4         int y = 100;
      5         int a = x / y;
      6         int b = 50;
      7         System.out.println(a + b);
      8     }
      9 }
    • 使用javap命令查看变编译字节码查看

    • 字节码执行过程展示:初始状态

      image-20200708204750374

    • 首先将操作数500压入操作数栈中

      image-20200708204953552

    • 然后操作数 500 从操作数栈中取出,存储到局部变量表中索引为 1 的位置

      image-20200708205029376

    • 然后操作数 100 从操作数栈中取出,存储到局部变量表中索引为 2 的位置

      image-20200729152950703

    • 将操作数 100 取出 

      image-20200729153015225

    • 读取本地变量 1 ,压入操作数栈

      image-20200729153119471

    • 读取本地变量 2 ,压入操作数栈

      image-20200729153138678

    • 两数相除,计算结果放在操作数栈顶,之后执行 istore_3 指令,将计算结果从操作数栈中弹出,存入局部变量 3 中

      image-20200729153203519

    • 将操作数 50 压入操作数栈

      image-20200729153239763

    • 将操作数 50 从栈顶弹出,保存在局部变量 4 中

      image-20200729153439077

    • 获取 System.out 输出流的引用,通过对应的常量池值

      image-20200729153532555

    • 将本地变量 3 的值取出,压入操作数栈中,准备进行加法运算

      image-20200729153919328

    • 执行加法运算后,将计算结果放在操作数栈顶

      image-20200729154017838

    • 调用静态方法 println() ,输出加法结果

      image-20200729154117269

    • main() 方法执行结束

      image-20200729154203288

    关于【符号引用 --> 直接饮用】的理解  

    1. 上面代码调用 System.out.println() 方法时,首先需要看看 System 类有没有加载,再看看 PrintStream 类有没有加载

    2. 如果没有加载,则执行加载,执行时,将常量池中的符号引用(字面量)转换为直接引用(真正的地址值)

    关于程序计数器的说明

      程序计数器始终计算的都是当前代码运行的位置,目的是为了方便记录方法调用后能够正常返回,或者是进行了CPU切换后,也能回来到原来的代码进行执行。  

    运行时数据区总结

    • 线程私有结构:程序计数器、虚拟机栈、本地方法栈

    • 每个虚拟机栈由由具体的栈帧组成,在栈帧的动态链接中,保存至对方法的引用

    • 方法区在 JDK7 之前,使用永久代实现,在 JDK8 之后,使用元空间实现

    • Minor GC 针对于新生区,Major GC 针对于老年区,Full GC 针对于整个堆空间和方法区

      

    大场面试题

    1. 百度
      • 三面:说一下JVM内存模型吧,有哪些区?分别干什么的?
    2. 蚂蚁金服:
      • Java8的内存分代改进
      • JVM内存分哪几个区,每个区的作用是什么?
      • 一面:JVM内存分布/内存结构?栈和堆的区别?堆的结构?为什么两个survivor区?
      • 二面:Eden和survior的比例分配
    3. 小米:
      • jvm内存分区,为什么要有新生代和老年代
    4. 字节跳动:
      • 二面:Java的内存分区
      • 二面:讲讲vm运行时数据库区
      • 什么时候对象会进入老年代?
    5. 京东:
      • JVM的内存结构,Eden和Survivor比例。
      • JVM内存为什么要分成新生代,老年代,持久代。新生代中为什么要分为Eden和survivor。
    6. 天猫:
      • 一面:Jvm内存模型以及分区,需要详细到每个区放什么。
      • 一面:JVM的内存模型,Java8做了什么改
    7. 拼多多:
      • JVM内存分哪几个区,每个区的作用是什么?
    8. 美团:
      • java内存分配
      • jvm的永久代中会发生垃圾回收吗?
      • 一面:jvm内存分区,为什么要有新生代和老年代?
  • 相关阅读:
    日志类
    sql查询数据并导出问题
    高并发系统设计(十七):【系统架构】微服务化后,系统架构要如何改造?
    高并发系统设计(十五):【消息队列】如何降低消息队列系统中消息的延迟?
    高并发系统设计(十四):【消息队列】如何消息不丢失?并且保证消息仅仅被消费一次?
    高并发系统设计(十三):消息队列的三大作用:削峰填谷、异步处理、模块解耦
    高并发系统设计(十二):【缓存的正确使用姿势】缓存穿透了怎么办?如何最大程度避免缓存穿透
    高并发系统设计(十一):【缓存的正确使用姿势】缓存如何做到高可用?
    ThinkPad X1 Carbon无法识别第二屏幕
    如何设置两个TPLink路由器桥接
  • 原文地址:https://www.cnblogs.com/h--d/p/14190412.html
Copyright © 2020-2023  润新知