ad

《深入理解 Java 虚拟机 JVM 高级特性与最佳实践(第3版)》_求知之路漫漫_2.2.7 直接内存

网友投稿 121 2023-11-07

【摘要】 本书摘自《深入理解 Java 虚拟机 JVM 高级特性与最佳实践(第3版)》一书中第2章,第2节,周志明著。

2.2.7 直接内存

直接内存 (Direct Memory) 并不是虚拟机运行时数据区的一部分,也不是《 Java 虚拟机规范》中定义的内存区域。但是这部分内存也被频繁地使用,而且也可能导致 OutOfMemoryError 异常出现,所以我们放到这里一起讲解。

在JDK1.4 中新加入了NIO(New Input/Output) 类,引入了一种基于通道 (Channel) 与缓冲区 (Buffer) 的 I/O 方式,它可以使用Native 函数库直接分配堆外内存,然后通过一 个存储在 Java 堆里面的 DirectByteBuffer 对象作为这块内存的引用进行操作。这样能在一 些场景中显著提高性能,因为避免了在 Java 堆和 Native 堆中来回复制数据。

《深入理解 Java 虚拟机 JVM 高级特性与最佳实践(第3版)》_求知之路漫漫_2.2.7 直接内存

显然,本机直接内存的分配不会受到Java 堆大小的限制,但是,既然是内存,则肯定 还是会受到本机总内存(包括物理内存、SWAP 分区或者分页文件)大小以及处理器寻址空 间的限制, 一般服务器管理员配置虚拟机参数时,会根据实际内存去设置-Xmx 等参数信 息,但经常忽略掉直接内存,使得各个内存区域总和大于物理内存限制(包括物理的和操作 系统级的限制),从而导致动态扩展时出现 OutOfMemoryError 异常。

2.3 HotSpot 虚拟机对象探秘

介绍完Java 虚拟机的运行时数据区域之后,我们大致明白了Java 虚拟机内存模型的 概况,相信读者了解过内存中放了什么,也许就会更进一步想了解这些虚拟机内存中数据 的其他细节,譬如它们是如何创建、如何布局以及如何访问的。对于这样涉及细节的问题, 必须把讨论范围限定在具体的虚拟机和集中在某一个内存区域上才有意义。基于实用优先 的原则,笔者以最常用的虚拟机HotSpot 和最常用的内存区域Java 堆为例,深入探讨一下 HotSpot 虚拟机在 Java 堆中对象分配、布局和访问的全过程。

2.3.1 对象的创建

Java 是一门面向对象的编程语言, Java 程序运行过程中无时无刻都有对象被创建出来。 在语言层面上,创建对象通常(例外:复制、反序列化)仅仅是一个new 关键字而已,而 在虚拟机中,对象(文中讨论的对象限于普通Java 对象,不包括数组和Class 对象等)的创 建又是怎样一个过程呢?

当 Java 虚拟机遇到一条字节码 new 指令时,首先将去检查这个指令的参数是否能在常 量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和 初始化过。如果没有,那必须先执行相应的类加载过程,本书第7章将探讨这部分细节。

在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需内存的大小在 类加载完成后便可完全确定(如何确定将在2.3.2节中介绍),为对象分配空间的任务实际上 便等同于把一块确定大小的内存块从Java 堆中划分出来。假设Java 堆中内存是绝对规整 的,所有被使用过的内存都被放在一边,空闲的内存被放在另一边,中间放着一个指针作 为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间方向挪动一段与对象大 小相等的距离,这种分配方式称为“指针碰撞”(Bump The Pointer)。但如果 Java 堆中的内 存并不是规整的,已被使用的内存和空闲的内存相互交错在一起,那就没有办法简单地进 行指针碰撞了,虚拟机就必须维护一个列表,记录上哪些内存块是可用的,在分配的时候 从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录,这种分配方式称 为“空闲列表”(Free List)。选择哪种分配方式由Java 堆是否规整决定,而Java 堆是否规 整又由所采用的垃圾收集器是否带有空间压缩整理 (Compact) 的能力决定。因此,当使用 Serial 、ParNew 等带压缩整理过程的收集器时,系统采用的分配算法是指针碰撞,既简单 又高效;而当使用CMS 这种基于清除 (Sweep) 算法的收集器时,理论上就只能采用较为 复杂的空闲列表来分配内存。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们 18664393530@aliyun.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:《Python学习笔记 从入门到实战》_更了解Python的途径之一_2.8.1 整数类型: int
下一篇:《Python+3自动化软件发布系统》Django 2实战_了解Python的更好方法_2.8.2 Model 示例
相关文章

 发表评论

暂时没有评论,来抢沙发吧~

×