JVM

2022-10-25  本文已影响0人  小名源治

1. JVM体系结构

JVM体系结构 堆和栈的关系

2.类加载器及双亲委派机制

类加载器

作用:加载class文件

类是模板,对象是具体的

public class Test {
    public static void main(String[] args) {
        //类是模板,对象是具体的
        Class<Test> testClass = Test.class;
    }
}

test1,test2,test3 三个对象都是类模板new出来的,通过第一次输出可以知道,三个对象是不一样的。
但是他们getClass后输出的结果就是一样的,因为getClass得到的是类的模板


类和对象
image.png

加载器的分类

双亲委派机制

APP ---> EXC ---> BOOT
BOOT中不存在 ---> EXC中不存在 ---> APP(当前应用)
双亲委派模型的工作流程是:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上,因此,所有的类加载请求最终都应该被传递到顶层的启动类加载器中,只有当父加载器在它的搜索范围中没有找到所需的类时,即无法完成该加载,子加载器才会尝试自己去加载该类。

举个例子

我们模拟Java中lang包下的String类,它一直会询问自己的父加载器有没有这个类,恰好BOOT中有这个类,但是其中没有main方法,就会报错。
假如是换一个名字,根加载器中没有这个Student类,那么它就能正常加载成功。


image.png image.png

3、native关键字

凡是被native修饰的,说明java的作用范围达不到了,会去调用c,c++语言的库!

以“start0();”方法为例

4、PC寄存器

程序计数器:Program Counter Register(PC计数器或者指令计数器更贴切):
-每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码(用来存储指向下一条指令的地址,即将要执行的指令代码),在执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不计

如果正在执行的是本地(Native)方法,这个计数器值则应为空(Undefined)

5、方法区

方法区 Method Area

6、栈

栈(先进后出):也叫栈内存,主管程序的运行,它的生命周期和线程同步;线程结束,栈内存也就释放了;对于栈来说,不存在垃圾回收问题;一旦线程结束,栈就“Over”;

栈运行原理:栈帧,程序正在执行的方法一定在栈的顶部
什么是栈溢出:(StackOverflowError)

package com.my.test;
//理解什么叫栈溢出
//为什么main()方法先执行后结束
public class Test03 {
    public static void main(String[] args) {
        Test03 test03 = new Test03();

        test03.a();
    }
    public void a(){
        b();
    };
    public void b(){
        a();
    };
}

7、三种JVM

8、堆(Heap)

Java堆(Java Heap)是虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,Java世界里“几乎”所有的对象实例都在这里分配内存。
Java堆是垃圾收集器管理的内存区域,因此它也被称作“GC堆”。
一个JVM只有一个堆内存,堆内存的大小是可以调节的。
堆内存中细分为三个领域:

GC垃圾回收:主要在伊甸园区和养老区

“OOM”:内存满了,堆内存不够

JDK8以后永久存储区更名为“元空间”

新生区

永久区

上一篇 下一篇

猜你喜欢

热点阅读