JVM 运行时数据区详解,写得非常好!

简介: 在接下来的几天想总结下,JVM相关的一些内容,比如下面的这三个内容算是比较核心知识点了

作者:小小木的博客 www.cnblogs.com/wyc1994666/p/11795781.html


在接下来的几天想总结下,JVM相关的一些内容,比如下面的这三个内容算是比较核心知识点了


1.运行时数据区域: 在运行时数据区里存储类Class文件元数据(方法区),对象和数组(堆),方法参数局部变量(栈)等。


2.垃圾回收机制: java 语言的优势之一就是它的自动内存管理,主要回收运行时数据区域的堆内存里的数据


3.类加载机制: 虚拟机首先需要把编译完成的字节码文件通过类加载器来加载到运行时数据区域


image.png


一个段Java代码的生命周期都会少不了上图这几个步骤,也就是Java代码首先会被编译成字节码文件,之后被类加载器加载到运行时数据区域,以及运行,垃圾收集器回收对象等等。


但今天我想介绍第一个知识点《运行时数据区域》


1 运行时数据区

Java虚拟机定义了一系列逻辑数据区域,有些是随着虚拟机的启动而创建,虚拟机的关闭而销毁。还有一部分是随着线程生命周期创建销毁的。


我们有必要深入了解这块的内容,因为它将决定服务器性能,首先我们需要对整个运行时区域由整体的认识并且了解了每个区域的生命周期以及作用之后才能通过相应的调参来提升系统性能。除此之外还有助于快速定位虚拟机的相关Error.


逻辑上可以划出一下6个区域分别是

image.png

1.1 PC寄存器

全名叫做 Program Counter Register 既然是叫做寄存器了那么肯定是需要存东西,那到底存的是什呢?


由于JVM同时可以处理多个线程所以就涉及到一些线程调度,当cpu暂停运行线程A把时间片让给线程B的时候我们需要保存线程A被暂停执行前的一些现场状态,需要记录当前执行到那一行字节码了,所以具备保存现场的功能。


每条线程都有自己的pc寄存器,在任意时刻虚拟机只会执行一个方法,如果执行的是方法不是native方法 pc寄存器则保存指向当前执行字节码的指令地址,如果执行的是native方法 pc寄存器会保存undefined。


1.2 java虚拟机栈

虚拟机栈也是每条线程私有的区域,里头存储栈帧(Frame),后面会重点介绍栈帧算是重点内容。方法的调用与返回基于栈帧来实现的。

image.png

1.3 虚拟机堆

在Java虚拟机中堆是所有线程都可以共享的内存区域,是存放所有类实例和数组对象的地方。在虚拟机启动就根据相关堆参数,创建堆,他也是垃圾收集器工作的主要区域。


堆内存里的对象不会被显式的回收,而是由垃圾回收器回收,为了配合垃圾收集器的特性我们可以把堆分为年轻代和老年代。


image.png


年轻代又分了Eden和survivor区,主要是为了配合垃圾回收算法而这么搞得。


1.4 方法区和运行时常量池

在Java虚拟机中 方法区是可提供各个线程共享的运行时内存区域,它存储了每一个类的结构信息,例如运行时常量池,字段和方法数据,构造函数和普通函数的字节码内容,一句话总结就是存储元数据地方


运行时常量池是class文件中每个类或接口常量池表的表示形式。它包括了若干不同的常量,比如 从编译期可知的数值字面量到运行时才能解析获得的方法或字段引用等等。


创建时机


每个运行时常量池都在Java虚拟机的方法区中分配,在加载类和接口到虚拟机之后创建对应的运行时常量池

image.png



1.5 本地方法栈

如果我们想再Java底层里调用别的语言代码的话就需要用到别的方法栈了,比如Java虚拟机的实现会用到传统的栈(C stack)来调用native方法,这个就是本地方法栈的应用,当然这个不是必须实现的,完全取决于虚拟机的实现。


2 栈帧:

首先看下栈帧在虚拟机内存中在什么位置,


image.png


栈帧是用来存储数据和部分过程结果的数据结构,同时也用来处理动态链接,方法返回,异常分派等工作。


栈帧的生命周期是跟方法一致的,随着方法的调用而创建,方法的结束或者异常而销毁。


每个栈帧都由局部变量表,操作数栈,动态链接组成的


2.1 局部变量表 (Local variable)

每个栈帧内部都包含一组称为局部变量表的列表,变量表的长度在编译期决定。另外关注公众号Java技术栈在后台回复JVM获取一份46页的JVM调优教程。


一个局部变量可以存储一个基本数据类型或一个对象引用(referance),returnAddress的数据。存储long或double需要两个局部变量才能存储。


当虚拟机要使用局部变量表里的数据时通过索引来定位,默认从0开始,由于long和double占用两个局部变量所以它的索引较特殊,取决于最小的那个值,比如某个long类型数据在索引n和n+1里存储了,那么它对应的索引值就是n. 虚拟机通过局部变量表来完成方法调用时的参数传递。如果是类方法,它的参数依次从0开始的位置传递到局部变量表,如果是实例方法则第0位置存储所在对象的引用(this),从1开始传递参数。


2.2 操作数栈 (Operating Stack)

操作数栈是属于栈帧中的栈,其实它的全名叫做当前栈帧的初操作数栈。栈,栈帧,操作数栈的关系需要梳理清楚:


栈:是虚拟机运行时数据区的一个逻辑区域,里面存储了一个个栈帧。


栈帧:栈帧代表一个方法的整个生命周期,里头存储了局部变量表,操作数栈,动态链接


操作数栈: 刚刚创建时操作数栈是空的。虚拟机提供一些指令从局部变量表把一些常量或者变量值加载到操作数栈,也提供了从操作数栈取走数据的指令。 调用方法时操作数栈用来准备调用方法参数以及接受方法的返回结果。


2.3 动态链接 (Dynamic Linking)。

动态链接是用来完成运行时绑定操作的。在栈帧中有一个指向常量池的当前类的一个引用。在class文件里一个方法要是调用其他方法或者方法其他成员变量,则需要通过符号引用来表示。


动态链接的作用就是将符号引用转换为直接引用。


类加载的过程中将要解析尚未被解析的符号引用,并且把对变量的访问转换为正确的偏移量。


相关文章
|
4月前
|
存储 安全 Java
JVM深入原理(七)(一):运行时数据区
栈的介绍:Java虚拟机栈采用栈的数据结构来管理方法调用中的基本数据,先进后出,每一个方法的调用使用一个栈帧来保存栈的组成:栈:一个线程运行所需要的内存空间,一个栈由多个栈帧组成栈帧:一个方法运行所需要的内存空间活动栈帧:一个线程中只能有一个活动栈帧栈的生命周期:栈随着线程的创建而创建,而回收会在线程销毁时进行栈的执行流程:栈帧压入栈内执行方法执行完毕释放内存若方法间存在调用,那么会压入被调用方法入栈,执行完后释放内存,再执行当前方法,直到执行完毕,释放所有内存。
61 0
|
4月前
|
存储 缓存 安全
JVM深入原理(七)(二):运行时数据区
堆的作用:存放对象的内存空间,它是空间最大的一块内存区域.栈上的局部变量表中,可以存放堆上对象的引用。静态变量也可以存放堆对象的引用,通过静态变量就可以实现对象在线程之间共享。堆的特点:线程共享:堆中的对象都需要考虑线程安全的问题垃圾回收:堆有垃圾回收机制,不再引用的对象就会被回收方法区的概述:方法区是存放基础信息的位置,线程共享,主要包括:类的元信息:保存了所有类的基本信息运行时常量池:保存了字节码文件中的常量池内容静态常量池:字节码文件通过编号查表的方式找到常量。
56 0
|
6月前
|
存储 Java C++
JVM 运行时数据区
Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存区域划分为若干个不同的数据区域。这 些区域都有各自的用途,以及创建和销毁的时间,有些区域随着虚拟机进程的启动而存在,有些区 域则是依赖线程的启动和结束而建立和销毁。Java 虚拟机所管理的内存被划分为如下几个区域 程序计数器(Program Counter Register):当前线程所执行的字节码的行号指示器,字节码解 析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,分支、循环、跳 转、异常处理、线程恢复等基础功能,都需要依赖这个计数器来完成; 为什么要线程计数器?因为线程是不具备记忆功能 Java 虚拟机
|
9月前
|
Java
JVM运行时数据区
1)虚拟机栈:每次调用方法都会在虚拟机栈中产生一个栈帧,每个栈帧中都有方法的参数、局部变量、方法出口等信息,方法执行完毕后释放栈帧 (2)本地方法栈:为native修饰的本地方法提供的空间,在HotSpot中与虚拟机合二为一
107 2
|
10月前
|
Java
JVM运行时数据区(内存结构)
1)虚拟机栈:每次调用方法都会在虚拟机栈中产生一个栈帧,每个栈帧中都有方法的参数、局部变量、方法出口等信息,方法执行完毕后释放栈帧 (2)本地方法栈:为native修饰的本地方法提供的空间,在HotSpot中与虚拟机合二为一 (3)程序计数器:保存指令执行的地址,方便线程切回后能继续执行代码
129 3
|
11月前
|
存储 SQL 小程序
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
这篇文章详细介绍了Java虚拟机(JVM)的运行时数据区域和JVM指令集,包括程序计数器、虚拟机栈、本地方法栈、直接内存、方法区和堆,以及栈帧的组成部分和执行流程。
189 2
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
|
11月前
|
Arthas 监控 Java
JVM知识体系学习七:了解JVM常用命令行参数、GC日志详解、调优三大方面(JVM规划和预调优、优化JVM环境、JVM运行出现的各种问题)、Arthas
这篇文章全面介绍了JVM的命令行参数、GC日志分析以及性能调优的各个方面,包括监控工具使用和实际案例分析。
910 3
|
4月前
|
Arthas 存储 算法
深入理解JVM,包含字节码文件,内存结构,垃圾回收,类的声明周期,类加载器
JVM全称是Java Virtual Machine-Java虚拟机JVM作用:本质上是一个运行在计算机上的程序,职责是运行Java字节码文件,编译为机器码交由计算机运行类的生命周期概述:类的生命周期描述了一个类加载,使用,卸载的整个过类的生命周期阶段:类的声明周期主要分为五个阶段:加载->连接->初始化->使用->卸载,其中连接中分为三个小阶段验证->准备->解析类加载器的定义:JVM提供类加载器给Java程序去获取类和接口字节码数据类加载器的作用:类加载器接受字节码文件。
402 55
|
5月前
|
Arthas 监控 Java
Arthas memory(查看 JVM 内存信息)
Arthas memory(查看 JVM 内存信息)
360 6
|
8月前
|
存储 设计模式 监控
快速定位并优化CPU 与 JVM 内存性能瓶颈
本文介绍了 Java 应用常见的 CPU & JVM 内存热点原因及优化思路。
879 166