JVM(三、运行时数据区)

devtools/2024/11/22 10:44:56/

1、运行时数据区

 数据区按照线程使用情况分两大类:

  • 由所有线程共享的数据区:字面意思,所有线程都使用同一个。

        堆和方法区、存储类的静态数据和对象数据、需要垃圾回收

  • 线程隔离的数据区:每个线程有自己的,例如:每个线程都有自己的程序计数器

        虚拟机栈、本地方法栈、程序计数器、不需要垃圾回收

1.1、程序计数器

        程序计数器(Program Counter Register)是一块较小的内存空间,线程私有,如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是本地(Native)方法,这个计数器值则应为空Undefined)。此内存区域是唯一一个《Java虚拟机规范》中没有规定任何OutOfMemoryError情况的区域。

1.2、Java虚拟机栈

        线程私有,是Java方法执行的线程内存模型,每个方法执行的时候,会创建一个栈帧,栈帧存储局部变量表、操作数栈、动态链接、方法出口等信息,每一个方法被调用就会有一个栈帧入栈,执行完毕则出栈。

        在《Java虚拟机规范》中,对这个内存区域规定了两类异常状况:如果线程请求的栈深度大于虚 拟机所允许的深度,将抛出StackOverflowError异常;如果Java虚拟机栈容量可以动态扩展,当栈扩展时无法申请到足够的内存会抛出OutOfMemoryError异常。

1.3、本地方法栈

        本地方法栈和虚拟机栈类似,区别是虚拟机栈执行的是Java方法,本地方法栈执行的是本地方法服务。Hot-Spot虚拟机直接就把本地方法栈和虚拟机栈合二为一。

1.4、堆

        Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例。
        Java堆是垃圾收集器管理的内存区域,由于垃圾回收器都是基于分代收集理论设计的,所以堆又被划分为新生代、老年代、永久代。新生代被划分为:Eden、From Survivor、To Survivor。当前Java虚拟机一般都是按照内存可扩展来实现的,通过-Xmx和-Xms设定,如果堆中没有内存完成实例分配,并无法扩展时,则会抛出OutOfMemoryError 异常。

1.5、方法区

        方法区各个线程共享的区域,用于存储已被虚拟机加载的类型信息、常量、静态变量,即时编译后的代码缓存等数据。

1.6、运行时常量池

        运行时常量池时方法区的一部分,

2、对象的创建、布局、访问

2.1、对象的创建

        在运行时数据区中,我们知道方法区中会存储类的信息,所以当用new关键字创建对象的时候,首先会检查这个常量池是否有类符号引用,并检查这个符号引用代表的类是否以为加载,如果没有则会进行类加载过程。

        类加载检查通过后,虚拟机将为新生对象分配内存,对象所需的内存大小在类加载完成后就可以确定。

        给对象分配内存可以根据内存是否规整分为两类:

  • 内存规整:指针碰撞
            当使用Serial、ParNew等带压缩整理过程的收集器时,垃圾回收后,会把使用过的内存放在一边,没有使用过的放在另一边,这样的话,在中间放一个指针作为分配内存的指示器,分配内存时把对象放在没有使用的内存,指针移动对象大小的位置。
  • 内存不规整:空闲列表
    当使用CMS这种基于清楚算法的收集器时,就会采用空闲列表的方式,空闲列表是虚拟机维护一个列表,记录哪些内存是可用的,在分配的时候从列表中找到一块足够的内存划分给对象,更新列表的值。

        分配内存时如何保证线程安全:

  • 对分配内存操作做同步处理-CAS
  • 对每个线程预先分配一小块内存(Thread Local Allocation Buffer TLAB),缓冲区用完了才需要同步操作,是否使用TLAB,可以通过-XX:+/-UseTLAB参数来设定。

在虚拟机中对象就算完成了,但是对于Java程序来看,后面还有初始化,执行Init方法等。

2.2、对象的内存布局

对象可以划分为三个部分:对象头、实例数据、对齐填充

2.2.1、对象头

对象头分为两个部分:
        Mark Word:哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,在32位和64位的机器中分别位32个bit和64个bit

        类型指针:对象执行类型元数据的指针

实例数据:真正存放对象数据的部分。

对齐填充:hotspot自动内存管理要求任何对象的大小都是8字节的倍数。所有需要对齐部分凑够8字节的倍数。

2.3、对象的访问定位

        访问方式主要有两种:句柄、直接指针

         句柄: 如果使用句柄访问的话,Java堆中将可能会划分出一块内存来作为句柄池, reference 中存储的就 是对象的句柄地址。

        直接指针:如果使用直接指针访问的话,Java堆中对象的内存布局就必须考虑如何放置访问类型数据的相关信息,reference中存储的直接就是对象地址。

 

        使用直接指针来访问最大的好处就是速度更快,它节省了一次指针定位的时间开销,由于对象访 问在Java 中非常频繁,因此这类开销积少成多也是一项极为可观的执行成本,就本书讨论的主要虚拟 机HotSpot 而言,它主要使用第二种方式进行对象访问。

http://www.ppmy.cn/devtools/135990.html

相关文章

测评部署和管理 WordPress 最方便的面板

新版宝塔面板快速搭建WordPress新手教程 - 倚栏听风-Morii - 博客园 初学者使用1Panel面板快速搭建WordPress网站 - 倚栏听风-Morii - 博客园 可以看到,无论是宝塔还是1Panel,部署和管理WordPress都有些繁琐,而且还需要额外去配置Nginx和M…

鸿蒙网络编程系列50-仓颉版TCP回声服务器示例

1. TCP服务端简介 TCP服务端是基于TCP协议构建的一种网络服务模式,它为HTTP(超文本传输协议)、SMTP(简单邮件传输协议)等高层协议的应用程序提供了可靠的底层支持。在TCP服务端中,服务器启动后会监听一个或…

fastify 连接 mysql

一、安装依赖 安装 fastify/mysql pnpm add fastify/mysql 二、示例 1. 创建 index.js 连接数据库,确保已经启动数据库,输入数据库的账号,密码,域名,端口,库名。 import Fastify from "fastify&…

如何删除pdf里的任意一页?删除PDF里任意一页的几种方法

如何删除pdf里的任意一页?尽管PDF文件具有许多优点,如跨平台兼容性和格式保真性,但在编辑和修改方面,它与像Word或Excel这类文档格式不同,通常不能像其他文档那样轻松进行直接的内容删除或修改。这让很多人以为&#x…

Linux-Apache静态资源

文章目录 静态资源权限设置 🏡作者主页:点击! 🤖Linux专栏:点击! ⏰️创作时间:2024年11月20日11点21分 静态资源 Apache配置静态资源 可以在网页上配置一个静态的FTP服务器,让用户…

如何确保Python爬虫程序的稳定性和安全性?

在当今数字化时代,Python爬虫被广泛应用于数据采集和信息抓取。然而,确保爬虫程序的稳定性和安全性是开发过程中的重要考虑因素。本文将探讨如何通过技术手段和最佳实践来提高Python爬虫的稳定性和安全性,并提供代码示例。 稳定性保障 1. 异…

layui 表格点击编辑感觉很好用,实现方法如下

1. 在 HTML 页面中引入 layui 的相关资源文件&#xff1a;html <link rel"stylesheet" href"https://cdn.staticfile.org/layui/2.5.6/css/layui.css"> <script src"https://cdn.staticfile.org/layui/2.5.6/layui.js"></script&…

Docker Compose安装部署PostgreSQL数据库

以下是一个完整的 PostgreSQL Docker Compose 部署教程&#xff0c;包括配置和部署详细步骤。本文将指导您如何在 Linux 服务器上使用 Docker Compose 来部署 PostgreSQL&#xff0c;并将数据持久化到指定路径。 1. 环境准备 确保您的系统上已经安装了以下软件&#xff1a; …