Java虚拟机运行时数据区精华总结

简介: Java虚拟机运行时数据区精华总结

说明

本篇文章是自己学习JVM的运行数据区的总结.


一,运行时数据区

Java虚拟机由三个子系统构成,分别是类加载子系统,JVM运行时数据区和执行引擎组成.一个Class文件先要经过类加载器–>运行时数据区–>执行引擎最终才会被执行.

而运行时数据区就是本篇文章所要重点讨论的.

Java虚拟机定义了在程序执行的时候所使用到的各种运行时数据区域.

其中一些数据区域是在Java虚拟机启动时创建的,仅在Java虚拟机退出时才被销毁.

其他数据区域是每个线程的,在创建线程时被每个线程所创建的数据区域,这些被每个线程所创建的数据区域,只有在线程退出的时候,才会被销毁.

如下图所示,这是一个比较经典的一幅结构图:

(1)程序计数器

Java虚拟机一次可以支持多个线程,所以这也就是我们经常提到的多线程.

每个Java虚拟机线程都有自己的程序计数器.

每个线程私有的.

在JVM中,多线程是通过线程轮流切换并分配处理器执行时间的方式来实现,在同一时刻一个处理器内核只会执行一条线程,处理器切换线程时并不会记录上一个线程执行到哪一个位置,所以为了线程切换后依然能恢复到上一次所执行到的位置,每个线程都需要各自独立的程序计数器.

提到程序计数器,你可能会想到操作系统中所学到的冯 ·诺伊曼计算机体系结构

如果你忘记了,整好可以通过下面这个资料来普及一下这个知识点:

冯 ·诺伊曼计算机体系结构的主要内容之一就是“程序预存储,计算机自动执行”!处理器要执行的程序(指令序列)都是以二进制代码序列方式预存储在计算机的存储器中,处理器将这些代码逐条地取到处理器中再译码、执行,以完成整个程序的执行。为了保证程序能够连续地执行下去,CPU必须具有某些手段来确定下一条取指指令的地址。程序计数器(PC )正是起到这种作用,所以通常又称之为‘指令计数器’。**CPU总是按照PC的指向对指令序列进行取指、译码和执行,也就是说,最终是PC 决定了程序运行流向。**故而,程序计数器(PC )属于特别功能寄存器范畴,不能自由地用于存储其他运算数据。

在程序开始执行前,将程序指令序列的起始地址,即程序的第一条指令所在的内存单元地址送入PC,CPU 按照 PC的指示从内存读取第一条指令(取指)。当执行指令时,CPU自动地修改PC 的内容,即每执行一条指令PC增加一个量,这个量等于指令所含的字节数(指令字节数),使 PC总是指向下一条将要取指的指令地址。由于大多数指令都是按顺序来执行的,所以修改PC 的过程通常只是简单的对PC 加“指令字节数”。

(2)Java虚拟机栈

Java虚拟机栈与程序计数器一样,也是每个线程私有的.

它的生命周期也是随着现成的生命周期诞生和销毁的.

每个Java虚拟机线程都有一个私有Java虚拟机栈,与该线程同时创建.

Java虚拟栈的责任:

当每个方法被执行的时候,Java虚拟机都会创建一个栈帧,用于存储局部变量表,操作数栈,动态连接,方法出口等信息.

每一个方法被调用到执行完毕的过程,就是一个栈帧在虚拟机栈中从入栈出栈的过程.

(3)本地方法栈

本地方法栈与虚拟机栈所发挥的作用是差不做的.

区别:

虚拟机栈为虚拟机执行Java方法服务(也就是执行字节码);

本地方法栈是为虚拟机使用到的本地方法服务.

Java方法:

这个不用多解释了吧,例如最常见的set和get方法,还有自定义的方法等.

本地方法(Native Method):

简单地讲,一个Native Method就是一个java调用非java代码的接口。

一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C。这个特征并非java所特有,很多其它的编程语言都有这一机制,比如在C++中,你可以用extern "C"告知C++编译器去调用一个C的函数。

(4)Java堆

Java堆(Java Heap)是被所有线程所拥有的一块内存区域,在虚拟机启动时创建.

此内存区域的唯一目的就是存放对象实例,运行的Java应用程序所有的对象实例都是在此分配内存的;

(5)方法区

方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已经被虚拟机加载类型信息,常量,静态变量,即时编译器编译后的代码缓存等数据.

(6)运行时常量池

运行时常量池(Runtime Constant Pool)是方法区的一部分.

Class文件中除了有类的版本,字段,方法,接口等描述信息外,还有一些信息是常量池表(Constant Pool Table),用于存放编译期生成的各种字面量与符号引用,这部分内存将在类加载后存放到方法区运行时常量池中.

字面量:

在计算机科学中,字面量(literal)是用于表达源代码中一个固定值的表示法(natation)。几乎所有计算机编程语言都具有对基本值的字面量表示,诸如:整数、浮点数以及字符串;而有很多也对布尔类型和字符类型的值也支持字面量表示;还有一些甚至对枚举类型的元素以及像数组、记录和对象等符合类型的值也支持字面量表示法。

字面量就是比如说int a = 1; 这个1就是字面量。又比如String a = “abc”,这个abc就是字面量。

在java中,一个java类将会编译成一个class文件。在编译时,java类并不知道引用类的实际内存地址,因此只能使用符号引用来代替。比如org.simple.People类要引用org.simple.Tool类,在编译时People类并不知道Tool类的实际内存地址,因此只能使用符号org.simple.Tool(假设)来表示Tool类的地址。而在类装载器装载People类时,此时可以通过虚拟机获取Tool类 的实际内存地址,因此便可以既将符号org.simple.Tool替换为Tool类的实际内存地址,及直接引用地址。

二,总结

JVM虚拟机包含:

  • 1,程序计数器
  • 2,Java虚拟机栈
  • 3,本地方法栈
  • 4,Java堆
  • 5,方法区(6,运行时常量池;)

1,程序计数器:

在JVM中,多线程是通过线程轮流切换并分配处理器执行时间的方式来实现,在同一时刻一个处理器内核只会执行一条线程,处理器切换线程时并不会记录上一个线程执行到哪一个位置,所以为了线程切换后依然能恢复到上一次所执行到的位置,每个线程都需要各自独立的程序计数器.

2,Java虚拟机栈:

当每个方法被执行的时候,Java虚拟机都会创建一个栈帧,用于存储局部变量表,操作数栈,动态连接,方法出口等信息.

每一个方法被调用到执行完毕的过程,就是一个栈帧在虚拟机栈中从入栈出栈的过程.

3,本地方法栈:

本地方法栈与虚拟机栈所发挥的作用是差不做的.

区别:

虚拟机栈为虚拟机执行Java方法服务(也就是执行字节码);

本地方法栈是为虚拟机使用到的本地方法服务.

4,Java堆:

Java堆(Java Heap)是被所有线程所拥有的一块内存区域,在虚拟机启动时创建.

此内存区域的唯一目的就是存放对象实例,运行的Java应用程序所有的对象实例都是在此分配内存的;

5,方法区:

方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已经被虚拟机加载类型信息,常量,静态变量,即时编译器编译后的代码缓存等数据.

6,运行时常量池:

运行时常量池(Runtime Constant Pool)是方法区的一部分.

Class文件中除了有类的版本,字段,方法,接口等描述信息外,还有一些信息是常量池表(Constant Pool Table),用于存放编译期生成的各种字面量与符号引用,这部分内存将在类加载后存放到方法区运行时常量池中.

参考资料:

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5.1

https://www.cnblogs.com/wjt6/p/9635752.html

http://blog.sina.com.cn/s/blog_62714d6a0100mjgs.html

https://www.cnblogs.com/chen-jack/p/7904510.html


目录
相关文章
|
2月前
|
Java
jvm复习,深入理解java虚拟机一:运行时数据区域
这篇文章深入探讨了Java虚拟机的运行时数据区域,包括程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区、元空间和运行时常量池,并讨论了它们的作用、特点以及与垃圾回收的关系。
68 19
jvm复习,深入理解java虚拟机一:运行时数据区域
|
2月前
|
存储 SQL 小程序
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
这篇文章详细介绍了Java虚拟机(JVM)的运行时数据区域和JVM指令集,包括程序计数器、虚拟机栈、本地方法栈、直接内存、方法区和堆,以及栈帧的组成部分和执行流程。
36 2
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
|
2月前
|
IDE Java 编译器
Java:如何确定编译和运行时类路径是否一致
类路径(Classpath)是JVM用于查找类文件的路径列表,对编译和运行Java程序至关重要。编译时通过`javac -classpath`指定,运行时通过`java -classpath`指定。IDE如Eclipse和IntelliJ IDEA也提供界面管理类路径。确保编译和运行时类路径一致,特别是外部库和项目内部类的路径设置。
|
2月前
|
Arthas 监控 Java
JVM知识体系学习七:了解JVM常用命令行参数、GC日志详解、调优三大方面(JVM规划和预调优、优化JVM环境、JVM运行出现的各种问题)、Arthas
这篇文章全面介绍了JVM的命令行参数、GC日志分析以及性能调优的各个方面,包括监控工具使用和实际案例分析。
55 3
|
4月前
|
存储 Java 程序员
JVM自动内存管理之运行时内存区
这篇文章详细解释了JVM运行时数据区的各个组成部分及其作用,有助于理解Java程序运行时的内存布局和管理机制。
JVM自动内存管理之运行时内存区
|
4月前
|
存储 算法 Java
JVM组成结构详解:类加载、运行时数据区、执行引擎与垃圾收集器的协同工作
【8月更文挑战第25天】Java虚拟机(JVM)是Java平台的核心,它使Java程序能在任何支持JVM的平台上运行。JVM包含复杂的结构,如类加载子系统、运行时数据区、执行引擎、本地库接口和垃圾收集器。例如,当运行含有第三方库的程序时,类加载子系统会加载必要的.class文件;运行时数据区管理程序数据,如对象实例存储在堆中;执行引擎执行字节码;本地库接口允许Java调用本地应用程序;垃圾收集器则负责清理不再使用的对象,防止内存泄漏。这些组件协同工作,确保了Java程序的高效运行。
30 3
|
4月前
|
消息中间件 设计模式 安全
多线程魔法:揭秘一个JVM中如何同时运行多个消费者
【8月更文挑战第22天】在Java虚拟机(JVM)中探索多消费者模式,此模式解耦生产与消费过程,提升系统性能。通过`ExecutorService`和`BlockingQueue`构建含2个生产者及4个消费者的系统,实现实时消息处理。多消费者模式虽增强处理能力,但也引入线程安全与资源竞争等挑战,需谨慎设计以确保高效稳定运行。
97 2
|
4月前
|
C# UED 开发者
WPF动画大揭秘:掌握动画技巧,让你的界面动起来,告别枯燥与乏味!
【8月更文挑战第31天】在WPF应用开发中,动画能显著提升用户体验,使其更加生动有趣。本文将介绍WPF动画的基础知识和实现方法,包括平移、缩放、旋转等常见类型,并通过示例代码展示如何使用`DoubleAnimation`创建平移动画。此外,还将介绍动画触发器的使用,帮助开发者更好地控制动画效果,提升应用的吸引力。
202 0
|
4月前
|
存储 Java 编译器
Java内存区域与内存溢出异常 - 运行时数据区
【8月更文挑战第2天】Java运行时数据区包括:1) 程序计数器:记录线程执行字节码的行号,线程私有;2) Java虚拟机栈:描述方法执行的内存模型,线程私有,深度过大抛出`StackOverflowError`;3) 本地方法栈:服务于Native方法,线程私有;4) Java堆:所有线程共享,对象实例在此分配内存;5) 方法区:存储类信息、常量等数据;6) 运行时常量池:方法区的一部分,存放字面量和符号引用。不当使用如无限创建对象或过度递归调用会导致各种内存溢出错误。
|
4月前
|
算法 Java
JVM常用运行时参数说明
JVM常用运行时参数说明