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

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

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

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

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

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

1 运行时数据区

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

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

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

1.1 PC寄存器

全名叫做 Program Counter Register 既然是叫做寄存器了那么肯定是需要存东西,那到底存的是什呢?
由于JVM同时可以处理多个线程所以就涉及到一些线程调度,当cpu暂停运行线程A把时间片让给线程B的时候我们需要保存线程A被暂停执行前的一些现场状态,需要记录当前执行到那一行字节码了,所以具备保存现场的功能。

每条线程都有自己的pc寄存器,在任意时刻虚拟机只会执行一个方法

如果执行的是方法不是native方法 pc寄存器则保存指向当前执行字节码的指令地址

如果执行的是native方法 pc寄存器会保存undefined

1.2 java虚拟机栈

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

1.3 虚拟机堆

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

为了配合垃圾收集器的特性我们可以把堆分为年轻代和老年代

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

1.4 方法区和运行时常量池

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

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

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

1.5 本地方法栈

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

2 栈帧:

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

栈帧是用来存储数据和部分过程结果的数据结构,同时也用来处理动态链接,方法返回,异常分派等工作。栈帧的生命周期是跟方法一致的,随着方法的调用而创建,方法的结束或者异常而销毁。
每个栈帧都由局部变量表,操作数栈,动态链接组成的

2.1 局部变量表 (Local variable)

每个栈帧内部都包含一组称为局部变量表的列表,变量表的长度在编译期决定。
一个局部变量可以存储一个基本数据类型或一个对象引用(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文件里一个方法要是调用其他方法或者方法其他成员变量,则需要通过符号引用来表示。

  • 动态链接的作用就是将符号引用转换为直接引用。
  • 类加载的过程中将要解析尚未被解析的符号引用,并且把对变量的访问转换为正确的偏移量。

JVM三部曲之运行时数据区 (第一部)的更多相关文章

  1. JVM学习笔记-运行时数据区

    不同于C,C++程序,Java程序的内存管理工作由Java虚拟机(JVM)接管,这减低了java程序员的负担,但如果出现内存泄露与溢出问题如报OutOfMemory,StackOverFlow异常错误 ...

  2. 1、JVM 内存模型+运行时数据区+JVM参数

    JMM(内存模型)  1.’主内存+每个线程有自己的内存 JVM运行时数据区 包含:1.程序计算器(每个线程自带):2.JAVA-STACK(每个线程自带):3.本地方法stack:4.堆:5.方法区 ...

  3. jvm内存模型(运行时数据区)

    运行时数据区(runtime data area) jvm定义了几个运行时数据区,这些运行时数据区存储的数据,供开发者的应用或者jvm本身使用.按线程共享与否可以分为线程间共享和线程间独立. 线程间独 ...

  4. JVM内存结构——运行时数据区

    在Java虚拟机规范中将Java运行时数据划分为6种,分别为: PC寄存器(程序计数器) Java栈 堆 方法区 运行时常量池 本地方法栈 一.PC寄存器(程序计数器) PC寄存器(Program C ...

  5. JVM之Java运行时数据区(线程隔离区)

    来源 JVM会在会在执行Java程序过程中把所管理的内存划分为若干区域,主要包括程序计数器(Program Counter Register),虚拟机栈(VM Stack),本地方法栈(Native ...

  6. JVM之Java运行时数据区(线程共享区)

    JVM运行时区域各线程共享的区域包括堆区和方法区. 堆区 堆区最最主要的功能是存储对象实例[上篇也提到过],因此Java垃圾回收的主要战场就是在堆区,因此也有称为GC堆区.如果堆区的内存不够会出现Ou ...

  7. 【转】Java运行时数据区简介及堆与栈的区别

    理解JVM运行时的数据区是Java编程中的进阶部分.我们在开发中都遇到过一个很头疼的问题就是OutOfMemoryError(内存溢出错误),但是如果我们了解JVM的内部实现和其运行时的数据区的工作机 ...

  8. JVM入门——运行时数据区

    这张图我相信基本上对JVM有点接触的都应该很熟悉,可以说这是JVM入门的第一课.其中的“堆”和“虚拟机栈(栈)”更是耳熟能详.下面将围绕这张图对JVM的运行时数据区做一个简单介绍. 程序计数器(Pro ...

  9. 深入理解JVM(2)——运行时数据区

    1.运行时数据区 1.1.程序计数器 记录当前线程正在执行的字节码指令的地址,如果正在执行的是 Native 方法,这个计数器值则为空. 1.2.虚拟机栈 每个 Java 方法在执行的同时会创建一个栈 ...

随机推荐

  1. Spring 梳理-bean作用域

    Spring定义了多种域 单例(Singleton):在整个应用中,只有一个实例 原型(Prototype):每次注入或者通过Spring应用上线文获取时,都创建一个bean实例 会话(Session ...

  2. linux 安装docker

    1.安装环境 此处在Centos7进行安装,可以使用以下命令查看CentOS版本 lsb_release -a 在 CentOS 7安装docker要求系统为64位.系统内核版本为 3.10 以上,可 ...

  3. S2-052 漏洞复现

    Structs2框架已知的漏洞编号如下: S2-005 S2-009 S2-016 (含S2-013) S2-019 S2-020 S2-021 S2-032 S2-037(含S2-033) DevM ...

  4. http转换为https

    1.下载ssl 证数 百度ssl 证数都有 其中以便宜ssl为例子 注册登陆 选择免费版 可以使用3个月: 申请过程中需要检测该域名是否为本人所有 ,所以邮箱检测或者域名配置 很简单检测就好了: 验证 ...

  5. MongoDB 学习笔记之 Aggregation Pipeline

    Aggregation Pipeline: 常用操作符介绍: $project:包含.排除.重命名和显示字段 $match:查询,需要同find()一样的参数 $limit:限制结果数量 $skip: ...

  6. win10下VSCode+CMake+Clang+GCC环境搭建

    win10下VSCode+CMake+Clang+GCC环境搭建 win10下VSCode+CMake+Clang+GCC环境搭建 安装软件 VSCode插件安装 新建文件夹, 开始撸代码 main. ...

  7. Spring Cloud Alibaba(一) 如何使用nacos服务注册和发现

    Nacos介绍 Nacos 致力于帮助您发现.配置和管理微服务.Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现.服务配置.服务元数据及流量管理. Nacos 帮助您更敏捷和容易地构 ...

  8. Jackson中@JsonProperty等常用注解

    Java生态圈中有很多处理JSON和XML格式化的类库,Jackson是其中比较著名的一个.虽然JDK自带了XML处理类库,但是相对来说比较低级 本文将介绍的Jackson常用注解:精简概述 Jack ...

  9. Java描述设计模式(15):责任链模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景描述 1.请假审批流程 公司常见的请假审批流程:请假天数 当 day<=3 天,项目经理审批 当 3<day<= ...

  10. Web安全 --Wfuzz 使用大全

    前言:  做web渗透大多数时候bp来fuzz   偶尔会有觉得要求达不到的时候 wfuzz就很有用了这时候 用了很久了这点来整理一次 wfuzz 是一款Python开发的Web安全模糊测试工具. 下 ...