你还在看《深入理解Java虚拟机》的运行时数据模型吗?

深入理解Java开发与Hibernate应用 本文将深入探讨Java开发中的关键概念,如继承、多态性和内存管理,同时结合Hibernate框架的数据库操作,包括数据插入、查询、表连接等。此外,还将涉及HTTP请求的处理、JUnit测试实践以及Spring框架的应用上下文和服务端逻辑。 阅读详情

你还在看《深入理解Java虚拟机》的运行时数据模型吗?

学习JVM必看的书籍无疑是《深入理解Java虚拟机》这本书了,在书中,关于运行时数据区域模型是这样描述的:

你还在看《深入理解Java虚拟机》的运行时数据模型吗?

在这里我们只针对HotSpot VM来说,它是OracleJDK和OpenJDK中所带的虚拟机,也是目前使用范围最广的Java虚拟机。在JDK7之前,这样的模型是正确的。但是到了JDK8,如图标红的部分,做了一些优化。

什么是方法区,什么是永久代,运行时常量池又是什么

  • “方法区”(Method Area),是线程共享的区域,用于存储已被虚拟机加载的类信息,常量,静态变量等数据。首先我们要知道,方法区是JVM的一种规范,是一个概念,而这个方法区的具体实现由各个虚拟机厂商去实现。
  • “永久代”(Permanent Generation)就是HotSpot虚拟机对于方法区的实现,也仅仅是针HotSpot才有的。
  • “运行时常量池”是方法区的一部分。用于存放编译期生成的各种字面量和符号引用。其特性是具备动态性。

优化一:字符串常量池从永久代划到Java堆

由于常量池具备动态性,在程序运行过程中会有大量的字符串常量在运行时常量池里产生,此时如果放在永久代,则无法恰当的设定永久代的大小,容易出现性能问题和内存溢出。下面一个例子证明在JDK8中,字符串常量池已经放在堆中:

String.intern()方法的作用是返回一个字符串引用,引用的是字符串常量池中的字符串(字面量),我们先来验证一下这个方法:

public class StringConstantsPoolTest {
public static void main(String[] args) {
String str = "abc"; //  str存储在常量池
String str2 = new String("abc");  // str2 存储在堆中
System.out.println(str == str2); //  结果为false ,堆中的引用并不等于常量池中的引用
str2 = str2.intern(); // 获取str2在常量池中的引用
System.out.println(str == str2); 
}
}

结果如下:

你还在看《深入理解Java虚拟机》的运行时数据模型吗?

证明 String.intern()方法返回了一个在常量池中的引用。
下面验证字符串常量池在堆中:
设置JVM参数:

-Xms10m -Xmx10m -XX:-UseGCOverheadLimit

public static void main(String[] args) {
List<String> list = new ArrayList();
int i = 0;
while(true){
list.add(String.valueOf(i++).intern());
}
}

结果如下:

你还在看《深入理解Java虚拟机》的运行时数据模型吗?

我们看到这时报的是Java堆空间内存溢出,说明字符串常量池是在堆中,注意,此时仅仅是字符串常量池转移到了堆中,但是运行时常量池依旧还是在方法区里

优化二:移除了永久代,引入“元空间”(Metaspace)

为什么移除永久代?

  1. 方法区大小难以设定,容易发生内存溢出 。永久代会存放Class的相关信息,一般这些信息在编译期间就能确定大小。但是如果是在一些需要动态生成大量Class的应用中,如:Spring的动态代理、大量的JSP页面或动态生成JSP页面等,由于方法区的大小在一开始就要分配好,因此就能难确定大小,容易出现内存溢出
  2. GC复杂且效率低 。方法区存储了类的元数据信息和各种常量,它的内存回收目标理应当是对这些类型的卸载和常量的回收。但由于这些数据被类的实例引用,卸载条件变得复杂且严格,回收不当会导致堆中的类实例失去元数据信息和常量信息。因此,回收方法区内存不是一件简单高效的事情。
  3. 促进HotSpot JVM与JRockit VM的融合 。JRockit没有方法区,移除永久代可以促进HotSpot JVM与JRockit VM的融合。

什么是元空间(Metaspace),为什么引入元空间

元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地 内存限制 。

元空间的特点:

  • 每个加载器有专门的存储空间。
  • 不会单独回收某个类。
  • 元空间里的对象的位置是固定的。
  • 如果发现某个加载器不再存活了,会把相关的空间整个回收。

总结

最终JVM(HotSpot)运行时数据区域模型如下:

你还在看《深入理解Java虚拟机》的运行时数据模型吗?

深入解析Java性能优化之道 Java虚拟机(JVM)内存模型是Java程序运行的基石。理解JVM内存模型是进行性能优化和故障排查的关键。JVM内存主要分为堆内存(Heap Memory)和非堆内存(Non-Heap Memory)。堆内存是JVM所管理的内存中最大的一块,主要用于存放对象实例,几乎所有对象的实例和数组都在这里分配内存。堆内存是由垃圾收集器管理的,因此,也被称为“GC堆”。 阅读详情

相关推荐

蓝牙耳机充电仓——功能框架

数据传输:大部分充电仓会跟耳机通信,控制耳机开机、关机和进入可搜索模式等等。蓝牙耳机给大家的生活带来便利,来讲讲TWS蓝牙耳机的搭档充电仓吧!方便携带:如果耳机单独带着,指定能弄丢一个,有了充电仓就安全多了。收纳保护:把珍爱的耳机放入充电仓里,防止丢失、磕碰、刮花等。给耳机充电:提供电力补给,让耳机持续使用。

改变自己现在能改变的,珍惜自己现在所拥有的 8954

Java虚拟机

实现通过类的权限限定名获取该类的二进制字节流的代码块叫做类加载器。启动类加载器(BootstrapClassLoader),使用C++语言编写,用来加载Java核心类库,它无法被应用程序直接使用。扩展类加载器(ExtensionClassLoader),使用Java编写,且父类加载器是Bootstrap,用来加载扩展库里面的类。系统类加载器(ApplicationClassLoader),根据Java的类路径(CLASSPATH)来加载Java类,参考JVMhttphttps。...

zhangzhang_one的博客 2454

【机电杂谈2】BLDC和PMSM的特点和区别

在日常生活中,小到电动玩具,大到电动汽车,永磁电机的身影可以说是无处不在。有刷直流电机、无刷直流电机、永磁同步电机由于其结构和输出特定的不同也被应用到不同的场合。如果你经常拆一些玩具和家电,就会看到大量的有刷直流电机和无刷直流电机,而永磁同步电机主要应用在高精度的工业伺服和电动汽车领域。本文就从电机的结构和控制方面,对这几种常见的永磁电机做简单的梳理和归纳。

2938

《深入理解java虚拟机》读书笔记

1. 运行时数据区域 1.1 程序技术器 可以看作是当前线程所执行的字节码的行号指示器,通过它来取下一条需要执行的指令。 线程私有内存。Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。 因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线

啊哈的博客 1505

ADS许可证配置全攻略:从破解文件放置到环境变量设置(实测有效版)

本文详细介绍了ADS许可证配置的全流程,包括环境准备、全新安装、破解文件部署和环境变量设置等关键步骤。针对常见的安装和授权问题,提供了实测有效的解决方案,帮助工程师快速完成ADS的配置与优化。

websocket5live的博客 381

5分钟搞懂知识抽取:如何把非结构化数据变成知识图谱的宝藏?

本文通过一个电商评论分析实战案例,详细解析了如何利用spaCy、Neo4j等工具,将非结构化文本数据转化为结构化知识图谱的完整流程。文章重点阐述了知识抽取的核心步骤,包括命名实体识别、关系抽取以及知识存储与查询,帮助读者快速掌握将数据转化为知识宝藏的关键技术。

weixin_29054245的博客 235

009_Java 虚拟机

在不同操作系统上安装与之对应的JDK后所虚拟出的一台计算机,该计算机上可以运行任意Java字节码文件,这也是Java实现跨平台的原因

李大能 2517

【Embabel Agent】生产级最佳实践与避坑指南

本文围绕架构师最关心的 8 大维度展开:测试策略(FakeOperationContext 实现 Action 级单元测试、Prompt 质量与敏感信息校验)、MCP 集成实战(STDIO/HTTP 双模式、自建 Server、Docker MCP 生态)、RAG 检索增强、OpenTelemetry 全链路可观测性与追踪、Docker/K8s 生产部署、API Key 管理与 @Tool 安全防护、模型选择/缓存/并行等性能优化,以及过度依赖 LLM、忽略错误处理等 8 大常见反模式避坑指南。

program哲学 309

深入理解Java虚拟机

JVM(Java Virtual Machine,Java 虚拟机)顾名思义就是用来执行 Java 程序的“虚拟主机”,实际的工作是将编译生成的.class 文件(字节码)翻译成底层操作系统可以运行的机器码并且进行调用执行,这也是 Java 程序能够跨平台(“一次编写,到处运行”)的原因(因为它会根据特定的操作系统生成对应的操作指令),Java语言最重要的特点就是跨平台运行。使用JVM就是为了支持与操作系统无关,实现跨平台。

故不积跬步无以至千里 5853

SAP Fiori Launchpad 上看不到任何 tile 应该怎么办?

中心UI组件是一个框架,为所有SAPFiori应用程序提供公共基础设施SAPFiorilaunchpad是所有SAPFioriUI的基础,并为SAPFiori应用程序提供基本功能,如登录,界面大小,应用程序之间的导航,和基于角色的应用程序目录。ABAP前端服务器包含所有基础设施组件,用于为客户端生成SAPFiori应用程序特定的UI,并与SAPBusinessSuite后端系统通信。SAPFiori应用程序的处理过程如下首先,客户端加载SAPFiori应用程序的界面。...

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 946

4、机器人建模、规划与控制及运动学知识解析

本博客深入解析了机器人建模、规划与控制的核心内容,涵盖运动学与动力学的基本原理,并结合典型应用场景探讨了移动机器人与操作器的控制策略。同时,博客还介绍了机器人技术的发展趋势及其在工业和服务领域的广泛应用。

desk3的博客 125

返回某个jsp页面时同时打开某个tab_你还在看《深入理解Java虚拟机》的运行时数据模型吗?...

学习JVM必看的书籍无疑是《深入理解Java虚拟机》这本书了,在书中,关于运行时数据区域模型是这样描述的:在这里我们只针对HotSpot VM来说,它是OracleJDK和OpenJDK中所带的虚拟机,也是目前使用范围最广的Java虚拟机。在JDK7之前,这样的模型是正确的。但是到了JDK8,如图标红的部分,做了一些优化。什么是方法区,什么是永久代,运行时常量池又是什么“方法区”(Method A...

weixin_39593354的博客 105

【SpringBoot 3.x 第43节】你还敢说 Spring 启动慢是“宿命”?Spring AOT 把启动剧本都提前写死了,你服不服?

🏆本文收录于《滚雪球学SpringBoot 3》,专门攻坚指数提升,本年度国内最系统+最专业+最详细(永久更新)。

**My Coding Family** 543

java数据模型_Java内存数据模型

本篇文章带来的是对Java内存数据模型的介绍,这对于我们深入理解Jvm虚拟机工作的原理和Java内存的划分大有裨益,好了,为了让我们理解的更为深刻,我们将会加入图片辅助的方法去理解。本篇博文的目录:一:Java内存数据模型的介绍二:线程私有内存三:程序计数器四:Java虚拟机栈五:本地方法栈六:Java堆七:方法区八:运行时常量池九:总结一:java内存数据模型的介绍java程序在运行的时候会在内...

weixin_30229705的博客 1043

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

深入理解Java虚拟机_1.Java内存区域

说明:本文章摘抄自《深入理解Java虚拟机:JVM高级特性与最佳实践 / 周志明著 第2版》 运行时数据模型 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自有各自的用途,以及创建和销毁时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而创建和销毁。 根据《Java虚拟机规范(Java SE 7版)》的规定,Ja...

Mr_luobo的博客 239

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Java内存数据模型

本篇文章带来的是对Java内存数据模型的介绍,这对于我们深入理解Jvm虚拟机工作的原理和Java内存的划分大有裨益,好了,为了让我们理解的更为深刻,我们将会加入图片辅助的方法去理解。 本篇博文的目录: 一:Java内存数据模型的介绍 二:线程私有内存 三:程序计数器 四:Java虚拟机栈 五:本地方法栈 六:Java堆 七:方法区 八:运行时常量池 九:总结 一:ja...

weixin_30855761的博客 117

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

【深入理解Java虚拟机 第2版】【学习笔记】JVM

涉及到JVM字节码指令的部分,我选择性的跳过了,毕竟不需要自己写虚拟机。重点是JVM的数据模型、垃圾回收和类加载机制。

wengcheng_k的专栏 531

《深入理解Java虚拟机》参数介绍

参数类型 Java启动参数共分为三类; 标准参数(-) 所有的JVM实现都必须实现这些参数的功能,而且向后兼容 非标准参数(-X) 默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容; 非稳定参数(-XX) 此类参数各个jvm实现会有所不同,将来可能会随时取消,需要慎重使用; 使用介绍 标准参数 可以通过:java -help 查看 用法 执行类 ja...

瑾析编程 213

跟着腾讯T4学架构:微服务+MySQL+Nginx+Redis+容器化+虚拟机

第1章、欢迎来到Docker世界 第2章、在容器中运行软件 第3章、软件安装的简化 第4章、持久化存储和卷间状态共享 第5章、网络访问 第6章、隔离——限制危险 第7章、在镜像中打包软件 第8章、构建自动化和高级镜像设置 第9章、公有和私有软件分发 第10章、运行自定义Registy 第11章、Docker Compose声明式环境 第12章、Docker Machine和Swarm集群。由于平台文章篇幅限制,细节内容过多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

m0_63437643的博客 1028

java虚拟机学习-JVM调优总结-典型配置举例(10)

java虚拟机学习-深入理解JVM(1) java虚拟机学习-慢慢琢磨JVM(2) java虚拟机学习-慢慢琢磨JVM(2-1)ClassLoader的工作机制 java虚拟机学习-JVM内存管理:深入Java内存区域与OOM(3) java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4) java虚拟机学习-JVM调优总结(5) java虚拟机学习-JVM调优...

dengkuituo0680的博客 188

Python编程:深入理解Python解释器

Python解释器是Python代码执行的核心引擎,理解其工作原理对于编写高效Python代码至关重要。

倔强老吕的博客 1493
上一篇: 阿里的朋友拿到头条Offer后,却反而头疼和纠结~
下一篇: Java如何在运行时识别类型信息?
大G哥
博客等级 码龄9年 5303粉丝 1408原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值