深解Java虚拟机(JVM)内存结构各部分总结【三层划分】

本文深入探讨了Java虚拟机(JVM)的内存结构,包括类加载过程、方法区、虚拟机栈、堆、对象头、程序计数器和本地方法栈。详细介绍了类加载的加载、链接和初始化阶段,以及双亲委派机制。此外,还阐述了方法区的演变,如JDK7的永久代到JDK8的元空间,并分析了虚拟机栈、堆的内存分配和管理。文章还讨论了对象头的内部结构,程序计数器的作用,以及执行引擎与JIT编译器的工作原理。最后,简要提到了垃圾回收的重要性。
摘要由CSDN通过智能技术生成


文章部分图形来源于尚硅谷,内容仅为个人对JVM的理解,如有错误请批评指正

1、第一层:Class文件由类装载子系统(类加载器Class Loader)加载进内存,有三个过程包括加载、链接、初始化。其中链接过程有验证、准备、解析子过程。

2、第二层:运行时数据区包括:
线程共享区域:方法区(落地实现jdk7永久代,jdk8元空间)、堆

线程私有区域:虚拟机栈、本地方法栈、程序计数器

3、第三层:执行引擎、本地方法接口(本地方法库)

三层划分总体结构:
在这里插入图片描述
三层划分结构细节:
在这里插入图片描述

第一层

一、类加载过程

1、加载:通过类的全限定名来获取定义此类的二进制流;在内存中生成一个Class对象,作为方法区该类各种数据的访问入口。
获取方式:
①从jar、war包中获取;
②从网络中获取;
③运行时计算机生成:Applet。

2、链接

验证:目的是确保Class文件包含的信息符合虚拟机要求
在这里插入图片描述
准备:正式为类变量分配内存并设置类变量赋零值的阶段( final修饰的变量在编译阶段就已经是被赋默认值了,在此阶段就直接显示赋值)。

解析
在这里插入图片描述
3、初始化
在这里插入图片描述
其中 clinit 方法是Java编译器自动生成并由JVM调用执行,用于对类中静态变量显示赋值执行静态代码块中的代码

  • 赋默认值:是对静态变量赋默认值,如byte、short、int ->0;boolean-> flase(布尔类型底层是int,1表示true)

  • 显示赋值:赋程序员指定的值,如:static int x = 1;此时显示赋值就是给x变量赋值为1,而不是0.

  • Java编译器生成 clinit 方法的条件:
    (1)类中有静态变量,并且要求其中一个静态变量是显示赋值的(如:static int x = 1;)
    (2)类中的静态变量,要有一个没有用 final 修饰过。用 final 修饰的变量会在链接阶段的准备阶段就会显示赋值,故不会生成 clinit 再去显示赋值;

  • 用static final 修改的变量,在链接阶段的准备阶段会直接显示赋值的两种情况:
    (1)用static final 修改的基本数据类型,是在链接阶段的准备阶段就会显示赋值;
    (2)用static final 修饰的 String 类型,分为两种:
    ①用字面量的形式(用双引号)赋值的,是在链接阶段的准备阶段就会显示赋值;
    如:static final String str = “HelloWord”;
    ②用 new String的方式,是在初始化阶段才会显示赋值。
    static final String str = new String(“HelloWord”);
    除了以上两种情况外基本都是在初始化阶段才会显式赋值(指的是用static final 修改的),可以这么理解,对于用static final 修饰的变量在创建时要使用数组和new关键字的,都是在初始化阶段显式赋值,简单理解就是能在编译器就确定的变量的值就是在链接阶段的准备阶段赋值了。

static + final 修饰的变量在何处进行显示赋值的最终结论:
使用 static + final 修饰,且显示赋值中不涉及到方法或构造器调用的基本数据类型或String类型的显示赋值,是在链接

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值