JVM的相关知识

一.JVM内存区域划分(JVM是一个Java进程)

  一个进程运行过程中就需要重操作系统这里申请到一些内存资源

JVM也是如此,搞一大块内存,供Java代码执行时使用

JVM把这一大块内存又划分成不同的区域,分别代表不同的用途

  各个部分的存储内容:

  栈:局部变量,方法的调用关系(如:递归)

  堆:new出来的对象里面的属性

  方法区:类对象,static成员,类被加载到内存后放的地方,方法的内容

  程序计数器:记录了当前线程执行下一个指令的内存地址

如:

  public class Test{

   public   int n=20;

   public static int a=10;

public static void main(String[]args){

Test t=new Test();

}

}

这里的的t是局部变量放在栈上

              n是new出来的内容放到堆上

              a是static成员放在方法区

误区:变量在哪里,和是不是“基本类型”,是否是“引用类型”没有关系

二、JVM类加载机制(把一个硬盘文件加载到内存中)

最开始写的.java文件,把它编译成.class文件(字节码)

运行.java程序,JVM会读取.class文件,把文件的内容放到内存中,就会构成一个.class对象

类健在的流程:

1.加载:找到.class文件,打开.class文件,读取.class文件的内容,并尝试解析格式

2.验证:检查一下当前.class文件的格式,是否符合要求

3.准备:给类对象分配内存

最终目标是构造成完整的内对象,分配内存+初始化

分配出来的内存空间,内容是0的值(此时此刻,类对象上的static成员也就是0)

4.解析:主要是初始化类对象中涉及到的一些字符串常量(其实字符串常量已经在.class文件中了,直接读到内存中就行了)

这里用符号引用替换直接引用的过程(符号5引用:此时.class文件中,不知道字符串真实的内存地址是哪里的,只能知道一个相对位置的偏移量,知道字符串的内容在.class文件的那个地方;等到把字符串内容加载到内存之后,就可以把真实的地址写换到刚才的符号引用这里了)

5.初始化:对类对象进行更具体的初始化操作,初始化静态成员,执行静态代码块,加载父类

三、双亲委派模型(描述加载构成中,如何找.class文件)

Bootstrap ClassLoader(负责加载JVM准库中的类):Java有一个标准文档,描述了都要提供哪些类

Extension  ClassLoader(负责加载JVM扩展的类):除了标准库之外,实现JVM的厂商,可能还会添加一些类

Application  ClassLoader(负责加载第三方库):像MySQL,jdbc等一下放在Maven中的依赖

双亲委派模型,就描述了类加载的流程:

1.从Application ClassLoader开始。不会立即搜索第三方库,而是先把任务委派给父亲,让父亲尝试加载

2.接着到了Extension  ClassLoader,它也不会立即搜索JVM扩展的类,而是把任务委派给他的父亲,让他的父亲尝试加载

3.接着到了Bootstrap ClassLoader,它也是把任务委派给自己的父亲,但是他没有父亲,那么他就自己搜索类了。

如果自己找到了这个类,就会进行后续的加载(也就和Extension、Application没有什么关系了)

如果没有找到这个类任务就会交给孩子

4、任务回到Extension  ClassLoader,就要搜索扩展库中的目录,看有没有匹配的.class文件

如果有的话,就进行后续加载也就和Application没有什么关系了

5、任务回到了Application ClassLoader,就要搜索第三方库的目录(往往是项目目录,以及和JVM的一些配置项有关-classpath有关系)

如果找到了类,就会进行后续加载

如果没有找到就会抛出一个异常

一个类什么时机会被加载?(懒汉模式用到了才加载)

1、构造类的实力

2、使用了类的静态方法/静态属性

3、子类的加载会触发父类

类加载了之后,后续使用就不必加载了(类对象已经是现成了的)

注:类卸载(把类对象干掉)

特殊情况:

一般来说类加载了之后,就不必考虑卸载了,一直保持到程序运行结束

有些特定的场景需要用到类卸载操作

有的服务器需要打“热补丁”代码有bug,正常操作应该是修改代码,重新编译,用新的版本代替就得版本,重启服务器

有些特殊情况,服务器不方便重启,就可以“打补丁”,通过一些特殊手段,把书序替换的类给卸载掉,直接用加载好的心得类替换(新版代码)(Java这里用的倒不是很多,Java的服务器一般都是分布式系统,天然就可以方便重启的)

不重启服务器,也能更新代码

“热”不需要重启,不需要重新编译,也不需要重启

相关推荐

  1. jvm相关知识

    2024-06-07 04:32:02       70 阅读
  2. JVM知识

    2024-06-07 04:32:02       56 阅读
  3. 如何学习JVM知识

    2024-06-07 04:32:02       41 阅读
  4. JVM相关

    2024-06-07 04:32:02       40 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-07 04:32:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-07 04:32:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-06-07 04:32:02       82 阅读
  4. Python语言-面向对象

    2024-06-07 04:32:02       91 阅读

热门阅读

  1. CSS中z-index不生效的原因和解决办法

    2024-06-07 04:32:02       32 阅读
  2. 21data 数据可视化

    2024-06-07 04:32:02       35 阅读
  3. Python 设计模式(行为型)

    2024-06-07 04:32:02       23 阅读
  4. 【设计模式】单例模式(创建型)⭐⭐⭐

    2024-06-07 04:32:02       29 阅读
  5. 完全背包(从二维数组到一维滚动数组)

    2024-06-07 04:32:02       29 阅读
  6. [高频]Linux中常见的命令及常见面试题

    2024-06-07 04:32:02       36 阅读
  7. 使用redis的setnx实现分布式锁

    2024-06-07 04:32:02       34 阅读
  8. vue-router 源码分析——3. 动态路由匹配

    2024-06-07 04:32:02       29 阅读
  9. flutter sdk升级之空安全启用

    2024-06-07 04:32:02       34 阅读