文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

JVM 内存架构和 GC 算法基础

2024-12-02 00:23

关注

内存管理的重要性

Java 垃圾收集器不能确保堆内存完全空闲,而且对于开发人员来说,不可能强制垃圾收集器在特定时间运行。因此,了解 Java 中的内存管理是如何工作的对开发程序会很有帮助。

了解内存管理有助于编写优化的内存效率代码,并有助于避免程序中任何与内存相关的问题,这些问题可能导致应用程序运行缓慢,并有助于避免 StackOverFlowError 和 OutOfMemoryError 等错误。

栈内存

栈是一种线性数据结构,是 Java 分配的静态内存,用于存储堆对象引用,也存储 Java 原始类型值。栈以后进先出 (LIFO) 顺序访问内存,并且栈比堆内存快。

每个线程在内存中创建自己的栈,这反过来又使栈内存线程安全。

Java 中的方法仅访问方法体(方法范围内)内的栈内存中的对象。当方法执行完成时,该方法对应的块会从栈中清除。

在上面的程序中,我们可以看到,当控件到达main方法时,栈中会有一个args的入口。然后当控件在下一行时,一个新条目被添加到栈中。

当控件超出方法的范围时,引用将从栈中删除。

如果栈内存已满,JVM 会抛出 StackOverFlowError。

堆内存

堆用于JVM在运行时为Java对象动态分配内存。任何新对象都存储在堆中,并且对象的引用(示例变量)存储在栈中。您可以在下面的示例中看到示例代码的变量如何存储在堆和堆栈中。

下面是上述代码片段在堆中的内存分配。

堆内存可以分解成更小的部分,称为代,它们是年轻代、年老/终身代和永久代。

年轻一代

所有新对象都在此内存段中分配。 年轻代由 Eden 和两个 Survivor 空间组成。当 Eden 填满时,垃圾收集发生在年轻代上,这称为 Minor GC。在 Minor GC 期间,来自年轻代的引用对象被移动到 Survivor 空间 #1,并且对象的年龄增加。

例如,在下图中,“对象 1”和“对象 2”将在第一次 Minor GC 之后移动到 Survivor 空间 #1,并且它们将具有指定的年龄。如果“对象 1”在第一次 Minor GC 中幸存下来,则年龄为零。现在如果“对象 1”在下一次 Minor GC 中也幸存下来,那么它将被移动到幸存者空间 2,并且年龄将再次增加。

在第二次 Minor GC 期间,驻留在 Survivor 空间 #1 中的对象(具有引用)将被移动到 Survivor #2,并且年龄将增加(即根据示例年龄将从零变为一)。并且从完整的年轻代空间中所有未引用的对象都将被删除。

老一代

老年代是存放长寿命对象(最老的对象)的地方。 年轻代对象有年龄的上限或阈值。 一旦对象达到该上限,则该对象将移至老一代或终身代。

终身代

这部分堆内存用于存储运行时类和方法的元数据。 从 JDK 8 开始,这部分内存已被 Java 完全删除,并被 Metaspace 概念所取代。您仍然可以设置 --XX:PermSize 和 -XX:MaxPermSize 配置。但是,如果您在 JDK 8 或更高版本上运行应用程序,则会在运行时收到警告。

元空间

这是从 JDK 8 版本开始引入的,它是一个可调整大小的内存区域并从本机内存中分配。元空间保存类元数据,它不是一个连续的内存位置。

每当 Metaspace 达到为 Metaspace 分配的最大大小时,Java 就会触发自动 GC 以释放 Metaspace 内存。

元空间选项是 -XX:MetaspaceSize=size 和 -XX:MaxMetaspaceSize=size

垃圾收集

Java程序编译并更改为字节码并在JVM(Java虚拟机)上运行。Java 程序的对象是在该程序的专用堆内存上创建的。随着时间的推移,会创建更多对象,并且程序不再需要一些对象(未引用和取消范围)。垃圾回收是 Java 执行自动内存管理并通过删除未引用对象来释放内存空间的过程。

JVM 结合了不同的垃圾收集算法。垃圾收集算法检查内存中的每个引用对象,其余对象被视为垃圾收集。

GC算法的类型

以下是 JVM 可用的 4 种类型的 GC 算法。

并行GC

专为具有中等或大量数据的多线程应用程序而设计,在多处理器环境中运行良好。但它会在垃圾收集期间冻结所有应用程序线程。 JVM 选项是 -XX:+UseParallelGC ,您可以选择使用 -XX:ParallelGCThreads= 设置并行线程数。

串行GC

主要设计用于单线程环境。 Liek Parallel GC,它还会在垃圾收集期间冻结所有应用程序线程。JVM 选项是 -XX:+UseSerialGC。

并发标记和渗漏(CMS)

这是一个并发 GC,旨在缩短 GC 暂停时间,并且不需要停止正在运行的应用程序来执行 GC。这就是为什么这个过程比串行或并行 GC 慢的原因。

它使用多线程进行垃圾收集,并且可以与垃圾收集器共享处理器资源。JVM 选项是 -XX:+UseConcMarkSweepGC。

G1 垃圾收集器(G1GC)

这是另一种最高效的并发 GC,专为具有大量内存的多处理器环境而设计。JVM 选项是 -XX:+UseG1GC。

选择 GC 算法的参数

除非您对 GC 时间有特定要求并且需要放置其他规范,否则最好让 JVM 自己选择 GC 算法。

如果要选择和配置 GC 算法,那么需要考虑的参数很少,如堆大小、CPU 核心数、应用程序数据集体积、吞吐量、暂停时间、延迟。

a、堆大小 - 分配给 JVM 的内存总量。更大的堆大小意味着 GC 将花费更多时间。更大的堆内存意味着与更少的堆内存相比,JVM 触发 GC 的频率不会那么频繁。JVM 选项是 -Xms=和 -Xmx=,其中 -Xms 表示最小值,-Xmx 是最大值。

b、CPU 核心 - GC 算法因 CPU 核心数量而异。其中一些是为单核 CPU 设计的,一些是为多核 CPU 设计的。

c、应用程序数据集 - 这是指应用程序使用的对象数量。创建更多数量的新对象,导致填充年轻代空间,需要更多的 GC 时间来释放内存。

d、吞吐量 - 它是完成应用程序任务所需的总时间(GC 外)的百分比。它与分配给 JVM 的内存成反比。

e、暂停时间 - GC 算法在内存回收期间停止应用程序所花费的时间。它根据不同的GC算法而有所不同。JVM 选项是 -XX:MaxGCPauseMillis=

f、延迟 - 它是应用程序的响应时间,直接取决于 GC 暂停时间。

根据上述参数,您必须选择最适合您的应用的 GC 算法。例如:

原文链接:https://dzone.com/articles/jvm-memory-architecture-and-gc

来源:新钛云服内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯