栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

【JVM系列(零)】虚拟机主要架构解析

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【JVM系列(零)】虚拟机主要架构解析

虚拟机主要架构解析 1,虚拟机概述

虚拟机的地位:虚拟机的存在使得 Java 具备跨平台特性,只要其他平台预装了JVM,Java程序就能够在上面执行。

我们更多的是关注虚拟机中的运行时数据区。一些关键数据的交互和执行都发生在此。

运行时数据区主要包括以下几部分:

线程隔离区

  • 程序计数器:在线程上下文切换时,程序计数器用于记录当前线程正在执行的字节码指令的地址
  • 本地方法栈:调用本地方法所需要的数据区
  • 虚拟机栈:方法调用所需要的数据区

线程共享区

  • 堆:存储实例对象
  • 方法区:存储类信息,常量信息

2,栈

我们这里主要说的是Java虚拟机栈(Java Virtual Machine Stack),也叫Java栈。每个线程在创建时都会创建一个虚拟机栈,其内部保存一个个的栈帧(Stack frame),对应着一次次的Java方法调用,是线程私有的。因此我们常说的方法入栈和出栈,其实是入栈帧和出栈帧。一个栈对应一个线程,一个栈帧对应一个方法。

栈的生命周期同线程,主要是负责程序的运行,保存方法的局部变量、部分结果,并参与方法的调用和返回。它的访问速度仅次于程序计数器。

栈帧的结构:

局部变量表:一个数字数组,主要用于存储方法参数和定义在方法体内的局部变量,这些数据类型包括各类基本数据类型、对象引用(reference),以及returnAddress类型。

操作数栈:在方法执行过程中,根据字节码指令,往栈中写入数据或提取数据,即入栈(push)和 出栈(pop)。主要用于保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间。

动态链接:一个指向运行时常量池中该栈帧所属方法的引用。其作用就是将常量池的符号引用转换为调用方法的直接引用。

方法返回地址:存放调用该方法的pc寄存器的值。

参考链接:https://www.yuque.com/u21195183/jvm/ar6bqp

3,堆

堆是虚拟机管理的一块最大的内存区域,线程共享,随着一个Jvm实例启动而创建并确定大小,当然其大小也可以指定。

堆的历史版本:

Jdk1.7及之前,堆分为:新生代、老年代、永久区;

Jdk1.8及之后,堆分为:新生代、老年代、元空间。

元空间与永久代最大的区别在于:元空间不在虚拟机设置的内存中,而是使用本地内存。

堆的大小分配默认按照以下方式执行:

  • 初始内存大小:物理电脑内存大小 / 64

  • 最大内存大小:物理电脑内存大小 / 4

手动设置方式:

  • “-Xms"用于表示堆区的起始内存,等价于-XX:InitialHeapSize
  • “-Xmx"则用于表示堆区的最大内存,等价于-XX:MaxHeapSize

内存分配策略:

针对不同年龄段的对象分配原则如下所示:

  • 优先分配到Eden

  • 大对象直接分配到老年代(尽量避免程序中出现过多的大对象)

  • 长期存活的对象分配到老年代

  • 动态对象年龄判断:如果survivor区中相同年龄的所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄。

  • 空间分配担保: -XX:HandlePromotionFailure

《Java虚拟机规范》规定,堆可以处于物理上不连续的内存空间中,但在逻辑上它应该被视为连续的。

我们知道堆是线程共享的,在并发场景下堆区内存的分配可能会有多个线程操作同一地址的情况,为此制定了TLAB(Thread Local Allocation Buffer)机制,即对Eden区进行进一步划分,每个线程都拥有一个私有的缓存区域。默认情况下,TLAB仅占有整个Eden区域的1%。

3.1,字符串常量池

String Table,在Java语言中有8种基本数据类型和一种比较特殊的类型String。这些类型为了使它们在运行过程中速度更快、更节省内存,都提供了一种常量池的概念。

参考链接:

https://www.yuque.com/u21195183/jvm/lep6m9

4,方法区

方法区位置:方法区逻辑上是堆的一部分,但可以看作是一块独立于Java堆的内存空间。

方法区结构:方法区用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等。

区分:

运行时常量池:方法区中的常量池;

常量池:class字节码文件中包含了常量池。

常量池中包含了:

  • 数量值
  • 字符串值
  • 类引用
  • 字段引用
  • 方法引用
5,小结

参考链接:

https://www.yuque.com/u21195183/jvm/zq4x30

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/395633.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号