”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > GraalVM 本机映像中的内存管理

GraalVM 本机映像中的内存管理

发布于2024-11-07
浏览:997

内存管理是计算机软件开发的重要组成部分,负责应用程序中内存的有效分配、利用和释放。其重要性在于增强软件性能,保证系统稳定性。

垃圾收集

垃圾收集 (GC) 在 Java 和 Go 等当代编程语言中至关重要。它自动检测并回收未使用的内存,从而减轻开发人员手动管理内存的需要。 GC 的概念最初出现在 20 世纪 50 年代末的 LISP 编程语言中,标志着自动内存管理的引入。

自动化内存管理的主要优势包括:

  • 防止内存泄漏,高效内存利用。
  • 简化开发流程,增强程序稳定性。

了解内存中“垃圾”的本质并识别可回收空间至关重要。在接下来的章节中,我们将从探索垃圾收集的基本原理开始。

引用计数算法 [George E. Collins 1966]

引用计数算法在对象标头中分配一个字段来跟踪其引用计数。此计数随着每个新引用而增加,并在删除引用时减少。当计数达到零时,该对象就有资格进行垃圾回收。

考虑以下代码:

首先创建一个由d引用的值为demo的字符串(图1)。

String d = new String("demo");

Memory Management in GraalVM Native Image

图 1 – 创建字符串后

然后,将 d 设置为 null。 demo的引用计数为零。在引用计数算法中,需要回收demo的内存(图2)。

d =null; // Reference count of 'demo' becomes zero, prompting garbage collection.

Memory Management in GraalVM Native Image

图 2 – 当引用无效时

引用计数算法在程序执行期间运行,避免了Stop-The-World事件,该事件会暂时停止程序以进行垃圾收集。然而,它的主要缺点是无法处理循环引用(图 3)。

例如:

public class CircularReferenceDemo {

  public CircularReferenceDemo reference;
  private String name;

  public CircularReferenceDemo(String name) {
    this.name = name;
  }

  public void setReference(CircularReferenceDemo ref) {
    this.reference = ref;
  }

  public static void main(String[] args) {
    CircularReferenceDemo objA = new CircularReferenceDemo("Ref_A");
    CircularReferenceDemo objB = new CircularReferenceDemo("Ref_B");

    objA.setReference(objB);
    objB.setReference(objA);

    objA = null;
    objB = null;
  }
}

这里,尽管使外部引用无效,但 objA 和 objB 之间的相互引用阻止了它们的垃圾回收。

Memory Management in GraalVM Native Image

图 3 – 循环引用

我们可以看到这两个对象都无法再访问了。然而,它们是互相引用的,因此它们的引用计数永远不会为零。因此,GC 收集器永远不会被通知使用引用计数算法对它们进行垃圾收集。

该算法实际上是通过使用 std::shared_ptr 在 C 中实现的。 std::shared_ptr 旨在管理动态分配对象的生命周期,在创建或销毁指向对象的指针时自动增加和减少引用计数。该智能指针是 C 标准库的一部分,提供强大的内存管理功能,可显着降低与手动内存处理相关的风险。每当复制 std::shared_ptr 时,托管对象的内部引用计数就会增加,反映新的引用。相反,当 std::shared_ptr 被破坏、超出范围或重新分配给不同的对象时,引用计数就会减少。当引用计数为零时,分配的内存会自动回收并销毁对象,
通过确保没有必要时不会保留分配的对象,有效防止内存泄漏。

可达性分析算法[1978]

可达性分析算法从 GC 根开始,遍历对象图。无法从这些根到达的对象被视为不可恢复,并成为收集的目标。

如下图所示,蓝色圆圈内的对象应该保持存活,灰色圆圈内的对象可以回收(图4)。

Memory Management in GraalVM Native Image

图 4 – 内存泄漏

该方法有效解决了引用计数算法固有的循环引用问题。从 GC 根无法到达的对象将被分类进行收集。

通常,被视为 GC 根的 Java 对象包括:

  • 当前方法范围内的局部变量。
  • 活动 Java 线程。
  • 类中的静态字段。
  • 来自本机代码的 JNI 引用。

GraalVM 原生镜像概述

GraalVM 提供了一个提前 (AOT) 编译器,它将 Java 应用程序转换为独立的可执行二进制文件,称为 GraalVM Native Images。这些二进制文件由 Oracle 实验室开发
封装应用程序和库类以及 GC 等运行时组件,允许在没有 Java 运行时环境 (JRE) 的情况下进行操作。

该过程涉及静态分析以确定可访问的组件、通过执行块进行初始化,以及通过创建应用程序状态快照以供后续机器代码翻译来完成。

Substrate VM 的基础知识

Substrate VM 是 GraalVM 套件的一个组成部分,由 Oracle 实验室精心策划。它是一个增强的 JVM,不仅支持提前 (AOT) 编译,而且还有助于执行 Java 以外的语言,例如 JavaScript、Python、Ruby,甚至是 C 和 C 等本机语言。 Substrate VM 的核心是一个复杂的框架,允许 GraalVM 将 Java 应用程序编译成独立的本机二进制文件。这些二进制文件不依赖于传统的 Java 虚拟机 (JVM) 来执行,这简化了部署和
操作流程。

Substrate VM 的主要功能之一是其专门的垃圾收集器,它针对需要低延迟和最小内存占用的应用程序进行了微调。该垃圾收集器擅长处理与本机映像不同的独特内存布局和操作模型,这与在标准 JVM 上运行的传统 Java 应用程序有很大不同。 Substrate VM 本机映像中缺少即时 (JIT) 编译器是一种战略选择,有助于最小化可执行文件的总体大小。这是因为它消除了包含 JIT 编译器和相关元数据的必要性,这些元数据的大小和复杂性都很大。

此外,虽然 GraalVM 是使用 Java 开发的,但这会带来一定的限制,特别是在本机内存访问方面。此类限制主要是出于安全考虑以及保持跨平台兼容性的需要。然而,访问本机内存对于优化垃圾收集操作至关重要。为了解决这个问题,Substrate VM 采用了一套专门的接口来促进与本机内存的安全高效的交互。这些接口是更广泛的 GraalVM 架构的一部分,使 Substrate VM 能够以类似于 C 等较低级语言的方式有效管理内存,同时保留 Java 的安全性和可管理性。

在实践中,这些功能使 Substrate VM 成为一种极其通用的工具,可以增强使用 GraalVM 编译的应用程序的功能和效率。通过允许开发人员
Substrate VM 利用更广泛的编程语言并将其编译为高效的本机二进制文件,突破了传统 Java 开发环境所能实现的界限。这使其成为需要高性能、减少资源消耗和多种语言支持的现代软件开发项目的宝贵资产。

Substrate VM 值得注意的元素包括:

  • 通过用于原始内存操作的指针接口指针和用于处理字大小值的 WordBase 接口 WordBase 等接口简化内存访问。

  • 将堆划分为包含不可变对象的预初始化段和用于动态对象分配的运行时段(图 5)。

Memory Management in GraalVM Native Image

图 5 – 本机映像中的内存管理

在运行时,Substrate VM 中所谓的镜像堆包含在镜像构建过程中创建的对象。堆的这一部分是用可执行二进制文件的数据部分中的数据预先初始化的,并且可以在应用程序启动时轻松访问。驻留在图像堆中的对象被认为是不朽的;因此,这些对象中的引用被
视为根指针 垃圾收集器。但是,GC 仅扫描部分映像堆中的根指针,特别是那些未标记为只读的指针。

在构建过程中,指定为只读的对象被放置在映像堆的特定只读部分中。由于这些对象永远不会保存对运行时分配的对象的引用,因此它们不包含根指针,从而允许 GC 在扫描期间绕过它们。同样,仅由原始数据或原始类型数组组成的对象也缺少根指针。此属性进一步简化了垃圾收集过程,因为这些对象可以从 GC 扫描中省略。

相反,Java 堆被指定用于保存在运行时动态创建的普通对象。堆的这一部分会定期进行垃圾收集,以回收不再使用的对象占用的空间。它被构造为具有老化机制的分代堆,随着时间的推移促进高效的内存管理。

预初始化、永久映像堆和动态管理的 Java 堆之间的这种划分使 Substrate VM 能够优化内存使用和垃圾收集效率,满足应用程序内存需求的静态和动态方面。

堆块

在 Substrate VM 的堆模型中,内存被系统地组织成称为堆块的结构。这些块的默认大小通常为 1024KB,形成一个连续的虚拟内存段,仅分配给对象存储。这些块的组织结构是一个链表,其中尾部块代表最近添加的段。这样的模型
促进高效的内存分配和对象管理。

这些堆块进一步分为两种类型:对齐和未对齐。对齐的堆块能够连续保存多个对象。这种对齐允许更简单地映射
对象到各自的父堆块,使内存管理更加直观和高效。在需要对象提升的场景中 - 通常是在垃圾收集期间和
内存优化——对象从其在父堆块中的原始位置移动到位于指定的“旧目标空间”中的目标堆块。此迁移是分代堆管理策略的一部分,该策略通过将年轻对象与旧对象分离来帮助优化垃圾收集过程,从而减少 GC 周期期间的开销。

本机映像中的垃圾收集器

GraalVM Native Image支持针对不同需求定制的各种GC:

  • 串行 GC: 适用于单线程应用程序的默认低占用空间收集器。

  • G1 垃圾收集器: 专为具有大堆大小的多线程应用程序而设计,增强了生成管理的灵活性。

  • Epsilon GC: 一种简约的收集器,处理分配但缺乏回收,最适用于可预测堆利用率的短期应用程序。

结论

总而言之,Substrate VM 通过结合专门的垃圾收集和结构化堆管理等先进技术,有效地优化了 GraalVM 中的内存管理。这些功能(包括堆块以及用于图像和 Java 堆的单独内存段)可简化垃圾收集并提高应用程序性能。由于 Substrate VM 支持多种编程语言并将其编译为高效的本机二进制文件,因此它展示了现代 JVM 框架如何超越传统边界,以提高不同应用程序环境中的执行效率和鲁棒性。这种方法为虚拟机技术和应用程序部署的未来发展设定了高标准。

版本声明 本文转载于:https://dev.to/yanev/memory-management-in-graalvm-native-image-4nbe?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何干净地删除匿名JavaScript事件处理程序?
    如何干净地删除匿名JavaScript事件处理程序?
    删除匿名事件侦听器将匿名事件侦听器添加到元素中会提供灵活性和简单性,但是当要删除它们时,可以构成挑战,而无需替换元素本身就可以替换一个问题。 element? element.addeventlistener(event,function(){/在这里工作/},false); 要解决此问题,请考虑...
    编程 发布于2025-03-10
  • 如何限制动态大小的父元素中元素的滚动范围?
    如何限制动态大小的父元素中元素的滚动范围?
    在交互式接口中实现垂直滚动元素的CSS高度限制,控制元素的滚动行为对于确保用户体验和可访问性是必不可少的。一种这样的方案涉及限制动态大小的父元素中元素的滚动范围。问题:考虑一个布局,其中我们具有与用户垂直滚动一起移动的可滚动地图div,同时与固定的固定sidebar保持一致。但是,地图的滚动无限期...
    编程 发布于2025-03-10
  • 对象拟合:IE和Edge中的封面失败,如何修复?
    对象拟合:IE和Edge中的封面失败,如何修复?
    To resolve this issue, we employ a clever CSS solution that solves the problem:position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%)...
    编程 发布于2025-03-10
  • 为什么PYTZ最初显示出意外的时区偏移?
    为什么PYTZ最初显示出意外的时区偏移?
    与pytz 最初从pytz获得特定的偏移。例如,亚洲/hong_kong最初显示一个七个小时37分钟的偏移: 差异源利用本地化将时区分配给日期,使用了适当的时区名称和偏移量。但是,直接使用DateTime构造器分配时区不允许进行正确的调整。 example pytz.timezone(...
    编程 发布于2025-03-10
  • HTML格式标签
    HTML格式标签
    HTML 格式化元素 **HTML Formatting is a process of formatting text for better look and feel. HTML provides us ability to format text without us...
    编程 发布于2025-03-10
  • 如何使用PHP从XML文件中有效地检索属性值?
    如何使用PHP从XML文件中有效地检索属性值?
    从php $xml = simplexml_load_file($file); foreach ($xml->Var[0]->attributes() as $attributeName => $attributeValue) { echo $attributeName,...
    编程 发布于2025-03-10
  • 可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    [2这里: https://webthemez.com/demo/sticky-multi-header-scroll/index.html </main> <section> { display:grid; grid-template-...
    编程 发布于2025-03-10
  • PHP阵列键值异常:了解07和08的好奇情况
    PHP阵列键值异常:了解07和08的好奇情况
    PHP数组键值问题,使用07&08 在给定数月的数组中,键值07和08呈现令人困惑的行为时,就会出现一个不寻常的问题。运行print_r($月份)返回意外结果:键“ 07”丢失,而键“ 08”分配给了9月的值。此问题源于PHP对领先零的解释。当一个数字带有0(例如07或08)的前缀时,PHP将...
    编程 发布于2025-03-10
  • 如何从PHP中的数组中提取随机元素?
    如何从PHP中的数组中提取随机元素?
    从阵列中的随机选择,可以轻松从数组中获取随机项目。考虑以下数组:; 从此数组中检索一个随机项目,利用array_rand( array_rand()函数从数组返回一个随机键。通过将$项目数组索引使用此键,我们可以从数组中访问一个随机元素。这种方法为选择随机项目提供了一种直接且可靠的方法。
    编程 发布于2025-03-10
  • 为什么我的CSS背景图像出现?
    为什么我的CSS背景图像出现?
    故障排除:CSS背景图像未出现 ,您的背景图像尽管遵循教程说明,但您的背景图像仍未加载。图像和样式表位于相同的目录中,但背景仍然是空白的白色帆布。而不是不弃用的,您已经使用了CSS样式: bockent {背景:封闭图像文件名:背景图:url(nickcage.jpg); 如果您的html,css...
    编程 发布于2025-03-10
  • 为什么尽管有效代码,为什么在PHP中捕获输入?
    为什么尽管有效代码,为什么在PHP中捕获输入?
    在php ;?>" method="post">The intention is to capture the input from the text box and display it when the submit button is clicked.但是,输出...
    编程 发布于2025-03-10
  • 为什么不使用CSS`content'属性显示图像?
    为什么不使用CSS`content'属性显示图像?
    在Firefox extemers属性为某些图像很大,&& && && &&华倍华倍[华氏华倍华氏度]很少见,却是某些浏览属性很少,尤其是特定于Firefox的某些浏览器未能在使用内容属性引用时未能显示图像的情况。这可以在提供的CSS类中看到:。googlepic { 内容:url(&#...
    编程 发布于2025-03-10
  • 如何检查对象是否具有Python中的特定属性?
    如何检查对象是否具有Python中的特定属性?
    方法来确定对象属性存在寻求一种方法来验证对象中特定属性的存在。考虑以下示例,其中尝试访问不确定属性会引起错误: >>> a = someClass() >>> A.property Trackback(最近的最新电话): 文件“ ”,第1行, AttributeError: SomeClass...
    编程 发布于2025-03-10
  • 在Java中使用for-to-loop和迭代器进行收集遍历之间是否存在性能差异?
    在Java中使用for-to-loop和迭代器进行收集遍历之间是否存在性能差异?
    For Each Loop vs. Iterator: Efficiency in Collection TraversalIntroductionWhen traversing a collection in Java, the choice arises between using a for-...
    编程 发布于2025-03-10

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3