jvm-Java虚拟机、附加面试题

1 篇文章 0 订阅

有哪些虚拟机器

HotSpot JRockit
java -version在这里插入图片描述

虚拟机作用:

去编译并解释 字节码文件(class、等待)

好处:

一处编译到处运行

内存管理

垃圾回收

虚拟机结构

在这里插入图片描述

多线程处理

共享 方法区、堆内存
单线程—》本地方法区、栈、程序计数器
在这里插入图片描述
执行引擎:将字节码文件编译成机器指令。再将反复执行的字节码文件缓存起来。共二次调用。

查看 栈 的指令集

Java文件先编译 编译后 查看栈内存的指令集合
先看一下代码

public class Test1 {
    public static void main(String[] args) {
        int i = 1;
        int j = 2;
        int z = i+j;
    }
}

查看编译后的文件Java指令:javap -v 类名.class
在这里插入图片描述
查看进程:jps 指令

类加载器 的执行流程

加载-----》 连接–验证(咖啡北北)—准备(赋值初始化)----解析(解析二进制码)—》初始化
类加载的信息 放在方法区里面
在这里插入图片描述
clinit:类变量赋值和静态代码快(子类一定要晚于父类)
init:该类的构造器

类加载器

在这里插入图片描述

面试常问:双亲委派机制

在类的加载过程中,应用程序类加载器是非常客气的(自己先不加载,一直向上委托)如果顶级父加载器能加载,默认加载。顶级父类加载不了,就开始向下委托。直到一个加载器完成对类的加载。

好处:

安全防止恶意篡改。

主动使用 被动使用

在这里插入图片描述

主动使用 :是否被初始化

运行时数据区

在这里插入图片描述

程序计数器

一个线程有且只有一个程序计数器。作用:用来存放当前线程的行号(也称行号指示器)。
多个线程来回切换执行,每个线程中的计数器行号很有可能不同。表示下一次执行该线程,表示从哪一行指令读起。至上而下
在这里插入图片描述

虚拟机栈

主要存放的就是栈帧,每一个方法就是一个栈帧。保持先进后出的原则。

每一个栈帧中存:局部变量表、操作数栈、动态连接、方法返回地址

局部变量表是一维数组主要存放,基本数据类型 引用类型 返回值类型。

局部变量在被加载的时候:就会初始化最大的局部变量表:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

操作数栈

他到底是个啥!

位于存放在栈帧中的单元。后进先出原则。int类型 布尔、字符、浮点、 占一个操作数。long、duppo类型 占 两个操作数。
最大操作数栈在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • Java代码
/**
 * 功能描述:程序计数器
 *
 * @author Songxianyang
 * @date 2022-11-16 21:53
 */
public class PCTest {
    public static final String SSS = "宋先阳";
    public static void main(String[] args) {
        int i = 99;
        int d = 11;
        int c = i+d;

        String name = "song";
        System.out.println(name);
        System.out.println(c);
        System.out.println(SSS);

    }

    public void test1() {
        int test = test();
        System.out.println(test);
    }

    public int test() {
        int i=2;
        int j=4;
        int n= i+j;
        return n;
    }
}
  • 字节码
Classfile /D:/work/project/huatech/yqmm-boot/spring-study/target/classes/com/song/boot/springstudy/jvm/PCTest.class
  Last modified 2022-11-22; size 1045 bytes
  MD5 checksum 6edd6ce518224237160d6f0a7a8db1c6
  Compiled from "PCTest.java"
public class com.song.boot.springstudy.jvm.PCTest
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #9.#37         // java/lang/Object."<init>":()V
   #2 = String             #38            // song
   #3 = Fieldref           #39.#40        // java/lang/System.out:Ljava/io/PrintStream;
   #4 = Methodref          #41.#42        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #5 = Methodref          #41.#43        // java/io/PrintStream.println:(I)V
   #6 = Class              #44            // com/song/boot/springstudy/jvm/PCTest
   #7 = String             #45            // 宋先阳
   #8 = Methodref          #6.#46         // com/song/boot/springstudy/jvm/PCTest.test:()I
   #9 = Class              #47            // java/lang/Object
  #10 = Utf8               SSS
  #11 = Utf8               Ljava/lang/String;
  #12 = Utf8               ConstantValue
  #13 = Utf8               <init>
  #14 = Utf8               ()V
  #15 = Utf8               Code
  #16 = Utf8               LineNumberTable
  #17 = Utf8               LocalVariableTable
  #18 = Utf8               this
  #19 = Utf8               Lcom/song/boot/springstudy/jvm/PCTest;
  #20 = Utf8               main
  #21 = Utf8               ([Ljava/lang/String;)V
  #22 = Utf8               args
  #23 = Utf8               [Ljava/lang/String;
  #24 = Utf8               i
  #25 = Utf8               I
  #26 = Utf8               d
  #27 = Utf8               c
  #28 = Utf8               name
  #29 = Utf8               MethodParameters
  #30 = Utf8               test1
  #31 = Utf8               test
  #32 = Utf8               ()I
  #33 = Utf8               j
  #34 = Utf8               n
  #35 = Utf8               SourceFile
  #36 = Utf8               PCTest.java
  #37 = NameAndType        #13:#14        // "<init>":()V
  #38 = Utf8               song
  #39 = Class              #48            // java/lang/System
  #40 = NameAndType        #49:#50        // out:Ljava/io/PrintStream;
  #41 = Class              #51            // java/io/PrintStream
  #42 = NameAndType        #52:#53        // println:(Ljava/lang/String;)V
  #43 = NameAndType        #52:#54        // println:(I)V
  #44 = Utf8               com/song/boot/springstudy/jvm/PCTest
  #45 = Utf8               宋先阳
  #46 = NameAndType        #31:#32        // test:()I
  #47 = Utf8               java/lang/Object
  #48 = Utf8               java/lang/System
  #49 = Utf8               out
  #50 = Utf8               Ljava/io/PrintStream;
  #51 = Utf8               java/io/PrintStream
  #52 = Utf8               println
  #53 = Utf8               (Ljava/lang/String;)V
  #54 = Utf8               (I)V
{
  public static final java.lang.String SSS;
    descriptor: Ljava/lang/String;
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
    ConstantValue: String 宋先阳

  public com.song.boot.springstudy.jvm.PCTest();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 18: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/song/boot/springstudy/jvm/PCTest;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=5, args_size=1
         0: bipush        99
         2: istore_1
         3: bipush        11
         5: istore_2
         6: iload_1
         7: iload_2
         8: iadd
         9: istore_3
        10: ldc           #2                  // String song
        12: astore        4
        14: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
        17: aload         4
        19: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        22: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
        25: iload_3
        26: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
        29: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
        32: ldc           #7                  // String 宋先阳
        34: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        37: return
      LineNumberTable:
        line 21: 0
        line 22: 3
        line 23: 6
        line 25: 10
        line 26: 14
        line 27: 22
        line 28: 29
        line 30: 37
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      38     0  args   [Ljava/lang/String;
            3      35     1     i   I
            6      32     2     d   I
           10      28     3     c   I
           14      24     4  name   Ljava/lang/String;
    MethodParameters:
      Name                           Flags
      args

  public void test1();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=1
         0: aload_0
         1: invokevirtual #8                  // Method test:()I
         4: istore_1
         5: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
         8: iload_1
         9: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
        12: return
      LineNumberTable:
        line 33: 0
        line 34: 5
        line 35: 12
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      13     0  this   Lcom/song/boot/springstudy/jvm/PCTest;
            5       8     1  test   I

  public int test();
    descriptor: ()I
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=4, args_size=1
         0: iconst_2
         1: istore_1
         2: iconst_4
         3: istore_2
         4: iload_1
         5: iload_2
         6: iadd
         7: istore_3
         8: iload_3
         9: ireturn
      LineNumberTable:
        line 38: 0
        line 39: 2
        line 40: 4
        line 41: 8
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      10     0  this   Lcom/song/boot/springstudy/jvm/PCTest;
            2       8     1     i   I
            4       6     2     j   I
            8       2     3     n   I
}
SourceFile: "PCTest.java"

动态连接

针对每一个栈帧(一个方法)指向常量池中引用地址(常量池在类得初始化后就确定下来啦)
常量池

Constant pool:
   #1 = Methodref          #9.#37         // java/lang/Object."<init>":()V
   #2 = String             #38            // song
   #3 = Fieldref           #39.#40        // java/lang/System.out:Ljava/io/PrintStream;
   #4 = Methodref          #41.#42        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #5 = Methodref          #41.#43        // java/io/PrintStream.println:(I)V
   #6 = Class              #44            // com/song/boot/springstudy/jvm/PCTest
   #7 = String             #45            // 宋先阳
   #8 = Methodref          #6.#46         // com/song/boot/springstudy/jvm/PCTest.test:()I
   #9 = Class              #47            // java/lang/Object
  #10 = Utf8               SSS
  #11 = Utf8               Ljava/lang/String;
  #12 = Utf8               ConstantValue
  #13 = Utf8               <init>
  #14 = Utf8               ()V
  #15 = Utf8               Code
  #16 = Utf8               LineNumberTable
  #17 = Utf8               LocalVariableTable
  #18 = Utf8               this
  #19 = Utf8               Lcom/song/boot/springstudy/jvm/PCTest;
  #20 = Utf8               main
  #21 = Utf8               ([Ljava/lang/String;)V
  #22 = Utf8               args
  #23 = Utf8               [Ljava/lang/String;
  #24 = Utf8               i
  #25 = Utf8               I
  #26 = Utf8               d
  #27 = Utf8               c
  #28 = Utf8               name
  #29 = Utf8               MethodParameters
  #30 = Utf8               test1
  #31 = Utf8               test
  #32 = Utf8               ()I
  #33 = Utf8               j
  #34 = Utf8               n
  #35 = Utf8               SourceFile
  #36 = Utf8               PCTest.java
  #37 = NameAndType        #13:#14        // "<init>":()V
  #38 = Utf8               song
  #39 = Class              #48            // java/lang/System
  #40 = NameAndType        #49:#50        // out:Ljava/io/PrintStream;
  #41 = Class              #51            // java/io/PrintStream
  #42 = NameAndType        #52:#53        // println:(Ljava/lang/String;)V
  #43 = NameAndType        #52:#54        // println:(I)V
  #44 = Utf8               com/song/boot/springstudy/jvm/PCTest
  #45 = Utf8               宋先阳
  #46 = NameAndType        #31:#32        // test:()I
  #47 = Utf8               java/lang/Object
  #48 = Utf8               java/lang/System
  #49 = Utf8               out
  #50 = Utf8               Ljava/io/PrintStream;
  #51 = Utf8               java/io/PrintStream
  #52 = Utf8               println
  #53 = Utf8               (Ljava/lang/String;)V
  #54 = Utf8               (I)V

看一下test1方法编译后得结果,然后去常量池中找对应得符号引用(#什么得)

public void test1();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=1
         0: aload_0
         1: invokevirtual #8                  // Method test:()I
         4: istore_1
         5: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
         8: iload_1
         9: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
        12: return
      LineNumberTable:
        line 33: 0
        line 34: 5
        line 35: 12
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      13     0  this   Lcom/song/boot/springstudy/jvm/PCTest;
            5       8     1  test   I

指向常量池中引用(#8)地址 。。。。。为什么着说

1: invokevirtual #8                  // Method test:()I
 #8 = Methodref          #6.#46         // com/song/boot/springstudy/jvm/PCTest.test:()I
#6 = Class              #44            // com/song/boot/springstudy/jvm/PCTest 那个类
#46 = NameAndType        #31:#32        // test:()I 那个方法
 #31 = Utf8               test    方法名
  #32 = Utf8               ()I    返回值类型

虚方法、非虚方法(实方法)

虚方法:在编译过程中无法确定的方法(多态、重写、抽象方法)。实方法:编译过程中可以确定下来的方法(私有方法、final修饰、静态方法、构造器)

方法返回地址

返回程序计数器地址(执行引擎执行),给调用者。A调用B B执行完了 把地址给A,A继续执行。有异常中断程序,或者被捕获。

12: return
9: ireturn

面试题
在这里插入图片描述

运行时数据区:堆

堆主要用来存什么:

存:您new出来的对象和数组。
对象的引用存在:栈帧中的本地变量表中。
类信息存在方法区中。

学习一下参数汇总:

jps:查询Java进程
这个地方是抄 :参考地址

-XX:+PrintGCDetails   :查看GC的详情
-XX:NewSize:设置年轻代最小空间大小
-XX:MaxNewSize:设置年轻代最大空间大小
-XX:PermSize:设置永久代最小空间大小
-XX:MaxPermSize:设置永久代最大空间大小
-XX:NewRatio:设置年轻代和老年代的比值。默认值-XX:NewRatio=2,表示年轻代与老年代比值为1:2,年轻代占整个堆大小的1/3
-XX:SurvivorRatio:设置年轻代中Eden区Survivor区的容量比值。默认值-XX:SurvivorRatio=8,表示Eden : Survivor0 : Survivor1 = 8 : 1 : 1
-XX:-OmitStackTraceInFastThrow:关闭(省略异常栈从而快速抛出),默认开启。如果想将所有异常信息都抛出,建议关闭。
-XX:+HeapDumpOnOutOfMemoryError:表示当JVM发生OOM时,自动生成DUMP文件。
-XX:HeapDumpPath=/usr/local/dump:dump文件路径或者名称。如果不指定文件名,默认为:java_<pid>_<date>_<time>_heapDump.hprof

在这里插入图片描述

参考地址

代码

打印GC详情:-XX:+PrintGCDetails
在这里插入图片描述

打印GC详情:-XX:+PrintGCDetails
Heap
 PSYoungGen      total 75776K, used 6503K [0x000000076bb80000, 0x0000000771000000, 0x00000007c0000000)
  eden space 65024K, 10% used [0x000000076bb80000,0x000000076c1d9f90,0x000000076fb00000)
  from space 10752K, 0% used [0x0000000770580000,0x0000000770580000,0x0000000771000000)
  to   space 10752K, 0% used [0x000000076fb00000,0x000000076fb00000,0x0000000770580000)
 ParOldGen       total 173568K, used 0K [0x00000006c3200000, 0x00000006cdb80000, 0x000000076bb80000)
  object space 173568K, 0% used [0x00000006c3200000,0x00000006c3200000,0x00000006cdb80000)
 Metaspace       used 3174K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 349K, capacity 388K, committed 512K, reserved 1048576K
  

出现OOM我们如何去监视他:

学习视频
实战一下:设置参数
在这里插入图片描述
代码
在这里插入图片描述
只是监控 并看不出来 什么问题 导致的OOM。继续往下学习。哈哈哈

堆区对象分配:

分为:新生代(伊甸园区,幸存者from区,幸存者to区)、老年代 。比例1:2,新生代8:1:1
创建的对象首先他会创建在伊甸园区,伊甸园满了之后处罚YGC,将没有具体引用指向的对象给回收掉。剩下的去到幸存者from区。依此类推。from区与to区来回赋值(并给一个标记age+1,当age到达15(默认值)去到老年代)

可以借鉴的文章
总结:复制并交换,谁空谁是to。
在推荐一篇 讲的还行

GC种类有那些?具体的自责是干嘛的

YGC\Minor GC 在伊甸园区满的时候,进行垃圾回收。
OGC\magor GC 老年代垃圾收集器
full GC 整堆收集器
不知道他说的对不对在这里插入图片描述
用户线程:那个一直在往堆里面创建对象

内存分配策略:

优先放到伊甸园区
大对象提前放到老年代
幸存者区对象大于或等于提前放到老年代(有点不明白)如果survivor 区中相同年龄的所有对象大小的总和大于survivor空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代,无须等到MaxTenuringThreshold 中要求的年龄。

逃逸分析

主要针对,方法内对象是否逃逸。未逃逸就直接在栈上分配。内部创建内部使用成为未逃逸,外部使用称为逃逸。
开发中能使用局部变量的,就不要使用在方法外定义。
在这里插入图片描述

对象内存布局

在这里插入图片描述
在这里插入图片描述

元空间 直接使用本地内存

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

面试题

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SteveCode.

永远年轻,永远热泪盈眶

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值