Java虚拟机内存模型

简介: 章节JVM结构运行时数据区(Java run time data area)方法区-线程共享堆区 -线程共享Java栈 -线程私有native 本地方法栈-线程私有PC寄存器 - 线程私有类加载器子系统ClassLoader 概述类加载时机ClassLoader 分类ClassLoader 工作原理装载链接初始化执行引擎1. JVM结构1、JVM 主要由类加载器、Java运行时数据区、执行引擎以及本地方法接口组成。

章节

  • JVM结构
  • 运行时数据区(Java run time data area)
    • 方法区-线程共享
    • 堆区 -线程共享
    • Java栈 -线程私有
    • native 本地方法栈-线程私有
    • PC寄存器 - 线程私有
  • 类加载器子系统
    • ClassLoader 概述
    • 类加载时机
    • ClassLoader 分类
    • ClassLoader 工作原理
      • 装载
      • 链接
      • 初始化
  • 执行引擎

1. JVM结构

1、JVM 主要由类加载器、Java运行时数据区、执行引擎以及本地方法接口组成。
2、Java 运行时数据区由 方法区、堆、Java栈、PC寄存器、本地方法栈组成。
3、本地方法栈、PC寄存器、Java栈是由每个线程私有的;方法区、堆是所有java线程共享的。

2.运行时数据区

2.1 Java 栈

1.Java栈与线程关联在一起,new Thread() 后会为当前线程创建对应的Java栈。
2.每个Java 栈中会包含多个栈帧,每个栈帧与每个运行中的方法对应起来。
3.运行一个方法创建一个栈帧,方法运行结束,栈帧弹出栈顶。

2.1.1 局部变量区

局部变量区 包含 方法参数、和局部变量、基本类型变量、对象引用。

2.1.2 操作数栈

进行入栈出栈基本操作。在计算时,操作数栈出栈,计算完毕后再入栈。

2.1.3 帧数据区

1.记录 存储类的相关信息的常量池的 指针 ,便于解析。
2.帮助方法正常返回:恢复调用该方法的栈帧、设置PC寄存器指向
调用方法对应的下一条指令、把返回值压入调用方法的栈帧中的操作
数栈中。

2.2 本地方法栈

本地方法栈类似于Java栈,主要存储本地方法调用状态。
本地方法栈为JVM调用native方法服务。

2.3 PC寄存器/程序计数器

记录当前线程即将执行的下一条指令的地址。

2.4 方法区

类型信息和类的静态变量都存储在方法区中
方法区中每个类存储了以下数据:
1.类及其父类的全限定名
2.类的类型 class or interface 
3.访问的修饰符 (public abstract final)
4.实现的接口的全限定名的列表
5.字段信息
6.方法信息
7.静态变量
8.常量池
9.ClassLoader 引用
10.Class引用

注意:可见类的所有信息都存储在方法区中,由于方法区是线程共享的,所以必须保证线程安全。

举例:两个类要同时加载一个尚未被加载的类,那么一个类会请求它
的ClassLoader去加载需要的类,另一个类只能等待而不会重复加
载。

2.4.1 常量池

常量池本身是方法区中的一个数据结构:
1、常量池中存储了如字符串(有些地方称之为字符串池)、final 变量值,类名和方法名常量。
2.常量池中数据在编译器就被确定,保存在.class文件中。
   分为两类:
    字面量:final变量、字符串
    引用量:类名、方法名、类和接口的全限定名
3.方法区对应持久代(Permanent Generation),默认大小16M,最大值
64M。大小通过参数来设置,-XX:permSize 指定初始值,-XX:MaxPermSize 指定最大值。

2.5 堆

1.堆是JVM管理的内存中最大的一块,是被所有Java线程共享的, 不是线程安全的,在JVM启动时创建。
2.堆用于存储对象实例以及数组值。
3.堆中有指向方法区中常量池中类信息的指针
4.堆中存放了指向方法表的指针
5.堆中实例数据包含了对象锁 monitor 对象,

2.5.1 分代管理模式-新生代、老年代

1.新生代(New Generation)
大多数情况下对象被分配在新生代,新生代由Eden Space 和两块相同大小的Survivor Space  组成。 后两者主要用于Minor GC 时的对象复制。
2.老年代 (Old Generation/Tenuring Generation)
在新生代存活时间较久的对象会被转入老年代,老年代进行垃圾回收的频率没有新生代高。

3.类加载器子系统(Class Loader)

3.1 类加载器概述

类加载器子系统负责加载编译好的.class 字节码文件,一般情况下类
在编译成.class 文件之后,立即被装入内存,使JVM可以实例化或以
其他方式使用加载后的类。JVM的类加载子系统支持在运行时的动态
加载(Java 反射),动态加载可以节省内存空间。

3.2 类加载的时机

类加载时机 含义 举例
静态加载 静态加载类,在编译时刻就需要加载所有可能使用到的类 如 new Word()
动态加载 属于延迟加载的模式,在java反射中会用到,首先节省内存,另外一个是动态加载类,这种方式在动态工厂方法中也会用到,这个生成类的util类只需要被加载一次就可以了 如 class.forName this.getClass() Class.class 三种方式实现运行时加载

3.3 ClassLoader 分类

  • 1.启动类加载器 (Bootstrap ClassLoader),java rt.jar 负责加载java 核心类
  • 2.扩展类加载器 (Extension ClassLoader),负责加载一些扩展功能的jar包
  • 3.系统类加载器 (System ClassLoader ),负责加载启动参数中制定的ClassPath 中的jar 包及目录。我们自己写的Java类也是由该ClassLoader加载的。
  • 4.用户自定义类加载器 (UserDefined Classloader):用户自定义类的加载规则,可以手动控制加载过程中的步骤。

3.4 ClassLoader的工作原理
类加载分为三个过程:装载、链接、初始化
3.4.1 装载

1. 通过类的全限定名和Classloader 加载类,主要是将指定的.class
 文件加载至jvm当中,类加载之后,jvm内部使用类的全限定名+
ClassLoader实例ID 标明类。
2.ClassLoader 实例 与 类实例位于堆中,他们的类信息位于方法区中
3.装载过程使用“ 双亲委派模型”,当一个ClassLoader要加载类时,他
会先请求他的双亲ClassLoader,即整个加载类的请求不断上抛,直
到启动类加载器。只有其双亲ClassLoader无法加载指定的类时,它
才会自己加载类。
4.不同类加载器之间是无法交互的,即使是同一个类,被不同的
ClassLoader加载,他们也无法感知彼此的存在。

3.4.2 链接

1.验证:校验.class文件的正确性,确保改文件是符合规范定义的
2.准备:为类分配内存,同时初始化类中的静态变量赋值为默认值。
3.解析:主要把类的常量池中的符号引用解析为直接引用。

3.4.3 初始化
定义:初始化类中的静态变量,并执行类中的static代码,构造函数。
初始化类的时机

1.通过new关键字、反射、clone、反序列化机制实例化对象
2.调用类的静态方法
3.使用类的静态变量或对其赋值
4.通过反射调用类的方法
5.初始化该类子类,其父类必须已经被初始化
6.具有main方法的类。
目录
相关文章
|
12天前
|
缓存 安全 Java
Java并发编程进阶:深入理解Java内存模型
Java并发编程进阶:深入理解Java内存模型
26 0
|
11天前
|
存储 算法 Java
深入浅出Java内存管理
【8月更文挑战第28天】Java的内存管理是每个Java开发者都绕不过去的技术话题。本文将通过生动的比喻和直观的例子,带你走进Java内存管理的奇妙世界。我们将一起探索对象在Java虚拟机中的生命周期,了解栈与堆的区别,以及垃圾回收机制如何默默守护着我们的应用程序。准备好,我们即将启程!
37 14
|
3天前
|
算法 安全 Java
Java内存管理:深入理解垃圾收集器
在Java的世界里,内存管理是一块基石,它支撑着应用程序的稳定运行。本文将带你走进Java的垃圾收集器(GC),探索它是如何默默守护着我们的内存安全。我们将从垃圾收集的基本概念出发,逐步深入到不同垃圾收集器的工作机制,并通过实例分析它们在实际应用中的表现。文章不仅旨在提升你对Java内存管理的认识,更希望你能通过这些知识优化你的代码,让程序运行更加高效。
21 3
|
11天前
|
监控 算法 Java
Java内存管理:垃圾收集器的工作原理与调优实践
在Java的世界里,内存管理是一块神秘的领域。它像是一位默默无闻的守护者,确保程序顺畅运行而不被无用对象所困扰。本文将带你一探究竟,了解垃圾收集器如何在后台无声地工作,以及如何通过调优来提升系统性能。让我们一起走进Java内存管理的迷宫,寻找提高应用性能的秘诀。
|
9天前
|
Kubernetes Cloud Native Java
云原生之旅:从容器到微服务的演进之路Java 内存管理:垃圾收集器与性能调优
【8月更文挑战第30天】在数字化时代的浪潮中,企业如何乘风破浪?云原生技术提供了一个强有力的桨。本文将带你从容器技术的基石出发,探索微服务架构的奥秘,最终实现在云端自由翱翔的梦想。我们将一起见证代码如何转化为业务的翅膀,让你的应用在云海中高飞。
|
1天前
|
安全 Java API
【性能与安全的双重飞跃】JDK 22外部函数与内存API:JNI的继任者,引领Java新潮流!
【9月更文挑战第7天】JDK 22外部函数与内存API的发布,标志着Java在性能与安全性方面实现了双重飞跃。作为JNI的继任者,这一新特性不仅简化了Java与本地代码的交互过程,还提升了程序的性能和安全性。我们有理由相信,在外部函数与内存API的引领下,Java将开启一个全新的编程时代,为开发者们带来更加高效、更加安全的编程体验。让我们共同期待Java在未来的辉煌成就!
21 11
|
2天前
|
安全 Java API
【本地与Java无缝对接】JDK 22外部函数和内存API:JNI终结者,性能与安全双提升!
【9月更文挑战第6天】JDK 22的外部函数和内存API无疑是Java编程语言发展史上的一个重要里程碑。它不仅解决了JNI的诸多局限和挑战,还为Java与本地代码的互操作提供了更加高效、安全和简洁的解决方案。随着FFM API的逐渐成熟和完善,我们有理由相信,Java将在更多领域展现出其强大的生命力和竞争力。让我们共同期待Java编程新纪元的到来!
23 11
|
10天前
|
缓存 Java
Java内存管理秘籍:掌握强软弱幻四大引用,让代码效率翻倍!
【8月更文挑战第29天】在Java中,引用是连接对象与内存的桥梁,主要分为强引用、软引用、弱引用和幻象引用。强引用确保对象生命周期由引用控制,适用于普通对象;软引用在内存不足时可被回收,适合用于内存敏感的缓存;弱引用在无强引用时即可被回收,适用于弱关联如监听器列表;幻象引用需与引用队列配合使用,用于跟踪对象回收状态,适用于执行清理工作。合理使用不同类型的引用车可以提升程序性能和资源管理效率。
32 4
|
11天前
|
Java 编译器 开发者
深入浅出Java内存模型
【8月更文挑战第28天】Java内存模型(JMM)是理解Java并发编程不可或缺的一环。本文通过浅显易懂的方式,带你一探JMM的奥秘,从基本概念到工作原理,再到实际代码示例,逐步揭开Java内存模型的神秘面纱。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的视角和深入的理解。
|
12天前
|
存储 缓存 Java
Java内存模型(JMM)
Java内存模型(JMM)是一个抽象概念,用于规范程序中各种变量(实例字段、静态字段及数组元素)的访问方式,确保不同Java虚拟机(JVM)上的并发程序结果一致可靠。JMM定义了主存储器(所有线程共享)与工作存储器(线程私有)的概念,线程间通过主存储器进行通信。JMM具备三大特性:原子性(确保基本读写操作的不可分割)、可见性(确保一个线程对共享变量的修改对其他线程可见)、有序性(防止指令被处理器或编译器重排序影响程序逻辑)。通过这些特性,JMM解决了多线程环境下的数据一致性问题。
下一篇
DDNS