Java JVM运行时数据区(Run-Time Data Areas)
作者:smileNicky 发布时间:2022-01-22 22:10:35
1、官网概括
引用官网说法:
The Java Virtual Machine defines various run-time data areas that are used during execution of a program. Some of these data areas are created on Java Virtual Machine start-up and are destroyed only when the Java Virtual Machine exits. Other data areas are per thread. Per-thread data areas are created when a thread is created and destroyed when the thread exits.
运行时数据区,是java虚拟机定义的在程序执行期间使用的各种运行时的数据区。这些运行时数据区分为两种,一种是在java虚拟机启动时创建,仅在java虚拟机退出时才被销毁,这种可以理解为线程共享的。另外一种是数据区是针对每个线程的,是在创建线程时创建的,并在线程退出时销毁这个数据区,这种可以理解为线程私有的。
2、图例和思维导图
JVM运行时数据区图例:
思维导图:Java虚拟机运行时数据区,虚拟机栈、本地方法栈、程序计数器是线程私有的,方法区、堆是线程共享的
3、方法区(Method Area)
what is method area? 下面摘录官网对方法区的描述
(1)、方法区是线程共享的内存区域,在虚拟机启动时创建
The Java Virtual Machine has a method area that is shared among all Java Virtual
Machine threads.
The method area is created on virtual machine start-up.
(2)、虽然方法区是堆的一个逻辑部分,但是其别名为非堆(Non-heap),目的是和堆区分开
The method area is analogous to the storage area for compiled code of a conventional language or analogous to the “text” segment in an operating system process
(3)、方法区存储运行时常量池、字段和方法数据,以及方法和构造函数的代码,包括在类和实例初始化和接口初始化中使用的特殊方法
It stores per-class structures such as the run-time constant pool, field and method data, and the code for methods and constructors, including the special methods (§2.9) used in class and instance initialization and interface initialization.
ps,注意点:如果方法区中的内存不能用于满足分配请求,Java 虚拟机将抛出一个OutOfMemoryError.
归纳:JVM方法区中存储了每个类的信息(包括类的名称、方法信息、字段信息),静态变量,常量已经编译器编译后的代码等。方法区是线程共享的,习惯上方法区也被称为“永久代”。如果方法区中的内存不能用于满足分配请求,Java 虚拟机将抛出内存不足异常
4、堆(Heap)
(1)、Java堆是Java虚拟机所管理内存中最大的一块,堆是运行时数据区,从中分配所有类实例和数组的内存
The Java Virtual Machine has a heap that is shared among all Java Virtual Machine threads. The heap is the run-time data area from which memory for all class instances and arrays is allocated.
(2)、堆是在虚拟机启动时创建的,是所有 Java 虚拟机线程之间共享的
The Java Virtual Machine has a heap that is shared among all Java Virtual Machine threads.
The heap is created on virtual machine start-up
注意:如果计算需要的堆多于自动存储管理系统所能提供的堆,Java 虚拟机将抛出一个 OutOfMemoryError.
归纳:Java 中的堆是用来 存储对象本身的以 及数组,堆是被所有 线程共享的。Java 堆从 GC 的角度还可以细分为: 新生代( Eden 区 、 From Survivor 区 和 To Survivor 区 )和老年代。。如果计算需要的堆多于自动存储管理系统所能提供的堆,Java 虚拟机将抛出一个 OutOfMemoryError.
5、Java虚拟机栈
Java虚拟机栈:Java Virtual Machine Stacks
(1)、每一个java虚拟机线程都有一个java虚拟机栈,在线程创建时候就创建虚拟机栈
Each Java Virtual Machine thread has a private Java Virtual Machine stack,
created at the same time as the thread
(2)、java虚拟机线程中的每一个方法对应一个栈帧;调用一个方法,就向虚拟机栈中压入一个栈帧;一个方法调用完成,就将改栈帧从栈中弹出
A Java Virtual Machine stack stores frames (§2.6)A new frame is created each time a method is invoked. A frame is destroyed when
its method invocation completes.
6、 栈帧(Stack Frame)
栈帧:每个栈帧对应一个被调用的方法,可以理解为一个方法的运行空间
每个栈帧中包括局部变量表(Local Variables)、操作数栈(Operand Stack)、动态链接(Dynamic Linking)、方法返回地址(Return Address)
局部变量表:方法中定义的局部变量以及方法的参数存放在这张表
操作数栈:以压栈和出栈的方式存储操作数的
动态链接:每个帧都包含对当前方法类型的运行时常量池的引用,以支持方法代码的动态链接,class方法的文件代码指的是要调用的方法和要通过符号引用访问的变量。动态链接将这些符号方法引用转换为具体方法引用,根据需要加载类以解析尚未定义的符号,并将变量访问转换为与这些变量的运行时位置相关联的存储结构中的适当偏移量(重点理解一下符号方法引用转换为具体方法引用,class文件编译为字节码之后,会有一个符号引用规范,动态链接就是将符号方法引用转换为具体方法引用)
方法返回地址:当一个方法开始执行后,只有两种方式可以退出,一种是遇到方法返回的字节码指令;一种是遇见异常,并且该异常不在方法内处理,则方法调用会 突然完成。执行athrow指令 ( § athrow ) 也会导致显式抛出异常,如果当前方法未捕获异常,则会导致方法调用突然完成。突然完成的方法调用永远不会向其调用者返回值。
注意:
如果线程中的计算需要比允许的更大的 Java 虚拟机堆栈,则 Java 虚拟机将抛出一个StackOverflowError.如果 Java 虚拟机堆栈可以动态扩展,并且尝试扩展但没有足够的内存来实现扩展,或者如果没有足够的内存可以为新线程创建初始 Java 虚拟机堆栈,则 Java 虚拟机机器抛出一个OutOfMemoryError.
7、程序计数器(The pc Register)
每个java虚拟机线程都有自己的程序计数器。在任何时候,每个 Java 虚拟机线程都在执行单个方法的代码,如果该方法不是 native,则该pc寄存器包含当前正在执行的 Java 虚拟机指令的地址。如果线程当前正在执行的方法是native,则 Java 虚拟机pc 寄存器的值是未定义的
The Java Virtual Machine can support many threads of execution at once (JLS §17). Each Java Virtual Machine thread has its own pc (program counter) register. At any point, each Java Virtual Machine thread is executing the code of a single method, namely the current method (§2.6) for that thread. If that method is not native, the pc register contains the address of the Java Virtual Machine instruction currently being executed. If the method currently being executed by the thread is native, the value of the Java Virtual Machine's pc register is undefined. The Java Virtual Machine's pc register is wide enough to hold a returnAddress or a native pointer on the specific platform.
8、本地方法栈(Native Method Stacks)
对于一般的方法,都是在java虚拟机栈指向,如果当前线程执行的方法是Native类型的,这些方法就会在本地方法栈中执行,学习本地方法栈可以和虚拟机栈对比。
native方法实例,可以点到String源码里看,如图,这个方法就是一个native方法:
异常情况:
1.栈深度大于已有深度:StackOverflowError
2.可扩展深度大于能够申请的内存:OutOfMemoryError
来源:https://blog.csdn.net/u014427391/article/details/116798445


猜你喜欢
- AbstractDetectingUrlHandlerMapping是通过扫描方式注册Handler,收到请求时由Abstrac
- 前言前一篇文章我们熟悉了HikariCP连接池,也了解到它的性能很高,今天我们讲一下另一款比较受欢迎的连接池:Druid,这是阿里开源的一款
- Android 活动条ActionBar的详解图一 图二 图三 图四 图五 ActionBar其提供的功能总结图一使用ActionB
- 背景银行跨行转账业务是一个典型分布式事务场景,假设 A 需要跨行转账给 B,那么就涉及两个银行的数据,无法通过一个数据库的本地事务保证转账的
- Android中子线程和UI线程之间通信的详细解释 1.在多线程编程这块,我们经常要使用Handler,Thread和Runnable这三个
- 看到软二的群里,某童鞋发了个自己的java大作业的截图,类似于一个图片,处理后,根据不同的灰度值,填充不同的字符。故,我也用C#来写个玩玩~
- PC端与Android手机端使用adb forword通信服务器端代码如下:import java.io.IOException; impo
- MyBatis动态sql动态sql处理简单的多参数查询常用标签标签说明if条件判断,与java中的if语句类似where为sql语句动态添加
- Servlet:在Servlet中拼接html内容JSP:在html中拼接javaJSP+JavaBean:利用javaBean将大量的代码
- JDK8已发布,写了一个datetime时间函数使用方法的小示例package datetime;import static java.ti
- 本文实例为大家分享了flutter实现底部导航栏的具体代码,供大家参考,具体内容如下一.flutter底部导航栏常用组件BottomNavi
- 一.异步冷数据流在Kotlin协程:协程的基础与使用中,通过使用协程中提供的flow方法可以创建一个Flow对象。这种方法得到的Flow对象
- IDEA 2020 源生是不支持中文的,感谢捷克工程师(可能是由国人实现)对我大天朝程序员的“照顾”,且不说这个必要性到底有多大,但从侧面体
- 目录前言常量池反编译代码验证字符串初始化操作总结前言在深入学习字符串类之前,我们先搞懂JVM是怎样处理新生字符串的。当你知道字符串的初始化细
- 1.获取String osName =System.getProperties().getProperty(&quo
- 一、前置说明本节大纲使用lombok插件的好处如何安装lombok插件使用lombok提高开发效率二、使用lombok插件的好处我们在jav
- multipartResolver上传文件配置1、gradle配置 compile ('commons-i
- 前言Spring是什么?它是一个应用程序框架,为应用程序的开发提供强大的支持,例如对事务处理和持久化的支持等;它也是一个bean容器,管理b
- 思路:先获得当前季度的开始和结束日期,在当前日期的基础上往前推3个月即上个季度的开始和结束日期/** * @param fla
- 一些初学Android的朋友可能会遇到JAVA的数据类型之间转换的苦恼,例如,整数和float,double型之间的转换,整数和String