JVM

作者: 小名源治 | 来源:发表于2022-10-25 15:53 被阅读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

加载器的分类

  • 虚拟机自带的加载器
  • 启动类(根)加载器 BOOT
  • 扩展类加载器 EXC
  • 应用程序(系统类)加载器 APP

双亲委派机制

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

  • 1、当 AppClassLoader加载一个class时,它首先不会自己去尝试加载这个类,而是把类加载请求委派给父类加载器ExtClassLoader去完成。

  • 2、当 ExtClassLoader加载一个class时,它首先也不会自己去尝试加载这个类,而是把类加载请求委派给BootStrapClassLoader```去完成。

  • 3、如果 BootStrapClassLoader加载失败(例如在 $JAVA_HOME/jre/lib里未查找到该class),会使用 ExtClassLoader来尝试加载;

  • 4、若ExtClassLoader也加载失败,则会使用 AppClassLoader来加载,如果 AppClassLoader也加载失败,则会报出异常 ClassNotFoundException。

举个例子

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


image.png image.png

3、native关键字

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

以“start0();”方法为例

  • 调用被native关键字修饰的方法,会进入本地方法栈
  • 然后会调用本地方法的本地方法接口(JNI)
  • JNI的作用:扩展java的使用,融合不同的编程语言为java所用!最初是c/c++
  • java诞生的使用,c/c++很流行,想要立足,就必须要用c/c++的程序
  • 因此,它在内存区域中专门开辟了一块标记区域Native Method Stack,来登记native方法
  • 在最终执行的时候,通过JNI(本地方法接口)来加载本地方法库中的方法
  • 平常用不到这类的方法,该方法多操控硬件资源

4、PC寄存器

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

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

5、方法区

方法区 Method Area

  • 又被称为静态区,它跟堆一样被所有线程共享
  • 它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据
  • 方法区中包含的都是整个程序中永远唯一的元素,如:class、static变量。

6、栈

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

  • 每个线程都包含一个栈区,栈中只保存基本数据类型的值和对象以及基础数据的引用。(8大基本类型+对象引用+实例的方法)
  • 每个栈中的数据(基本数据类型和对象的引用)都是私有的,其它栈是无法进行访问的。
  • 栈分为三个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。

栈运行原理:栈帧,程序正在执行的方法一定在栈的顶部
什么是栈溢出:(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

  • sun公司的HotSpot(Java HotSpot(TM) 64-Bit Server VM (build 25.152-b16, mixed mode))
  • Oracle公司的 JRockit
  • IBM J9 VM

8、堆(Heap)

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

  • 新生区(伊甸区)young/new
  • 养老区old
  • 永久区perm


    image.png

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

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

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

新生区

  • 类:诞生和成长以及死亡的地方
  • 伊甸园区:所有的对象都是由伊甸园区new出来的

永久区

  • 概念:
    这个区域常驻内存,用来存放JDK自身携带的Class对象、interface元数据、存储的是java运行时的一些环境或者类信息
    这个区域不存在垃圾回收;除非关闭虚拟机才会释放这个区域的内存

相关文章

  • 深入JVM内核 目录

    深入JVM内核 目录 深入JVM内核1 初识JVM深入JVM内核2 JVM运行机制深入JVM内核3 常用JVM配置...

  • JVM内存模型(jvm 入门篇)

    概述 jvm 入门篇,想要学习jvm,必须先得了解JVM内存模型,JVM内存模型,JVM内存模型,JVM内存模型,...

  • Jvm(一)-Java虚拟机的内存管理

    [toc] JVM JVM回顾 1. 什么是 JVM JVM是Java Virtual Machine(Java虚...

  • JVM介绍系列文章

    知晓JVM系列(一):对JVM总览知晓JVM系列(二):JVM内存管理机制与优化初探知晓JVM系列(三) :常用的...

  • 科普

    1.JVM/JRE/JDK关系JVM

  • JVM

    JVM之内存模型JVM之对象定位与访问JVM之Java垃圾回收机制JVM之类加载

  • JVM

    栈容量由-Xss指定深入理解JVM—JVM内存模型 JVM内存模型和JVM参数的关系

  • JVM基础知识系列

    JVM基础系列 JVM知识点扫盲系列(1) JVM知识点扫盲系列(2) JVM内存的那些事 JVM类加载的那些事 ...

  • (过时、作废)android 多线程 — GC

    简单解析下JVM 先说下 JVM,虽然上篇文章在讲内存时介绍了 JVM ,但是我在这里还是以 JVM 开头,JVM...

  • 技术文章罗列

    JVM JVM知识点详解JVM初步诊断JVM内存模型 Java Api java8 stream Api讲解(上)...

网友评论

      本文标题:JVM

      本文链接:https://www.haomeiwen.com/subject/waeuzrtx.html