JAVA和Nginx 教程大全

网站首页 > 精选教程 正文

探秘 JVM:内存结构

wys521 2024-11-18 18:03:22 精选教程 38 ℃ 0 评论

代码如诗,你我皆为诗人。大家好,我是水哥,一个在软件开发领域深耕多年的资深工程师。

今天水哥想聊聊 JVM 的内存结构。

JVM 内存结构是指 JVM 运行 Java 程序时候的数据区(Run-Time Data Areas)的结构,主要有几个部分:

程序计数器(Program Counter 简称 PC)

JVM 可以同时支持多个线程的执行。每个 JVM 线程都有自己的程序计数器(pc)。pc 包含当前正在执行的 JVM 指令的地址。

栈(Stack)

每个 JVM 线程都有自己的私有 JVM 栈,这个栈在线程创建时同时创建。JVM栈存储栈帧(frames)。栈保存局部变量和部分结果,并在方法调用和返回时发挥作用。

如果线程需要栈的空间超过栈的容量,JVM 将抛出我们耳熟能详的报错 StackOverflowError

如果 JVM 无法动态扩展栈空间,或者,如果无法获得足够的内存来为新线程创建初始栈,JVM 将抛出另一个我们耳熟能详的报错 OutOfMemoryError

我们可以根据应用的特定需求,通过修改 JVM 启动参数调整栈的大小,包括初始值、最小值、最大值。

堆(Heap)

JVM 拥有一个所有 JVM 线程共享的堆。堆是分配所有类实例和数组内存的地方。堆在虚拟机启动时被创建。对象的堆存储由垃圾收集器(GC)回收;对象永远不会被显式地释放。

如果无法提供足够的内存来满足计算所需的更多堆内存,JVM 将抛出 OutOfMemoryError

我们可以根据应用的特定需求,通过修改 JVM 启动参数调整堆的大小,包括初始值、最小值、最大值。

方法区(Method Area)

JVM 拥有一个所有 JVM 线程共享的方法区。方法区存储每个类的结构,如运行时常量池、字段和方法数据,以及用于类和接口初始化及实例初始化的特殊方法的代码。

方法区在虚拟机启动时被创建。尽管方法区在逻辑上是堆的一部分,但简单的实现可能会选择不对方法区进行垃圾回收或压缩。

如果无法在方法区中获得内存以满足分配请求,JVM 将抛出 OutOfMemoryError

我们可以根据应用的特定需求,通过修改 JVM 启动参数调整方法区的大小,包括初始值、最小值、最大值。

常量池(Constant Pool)

运行时常量池是每个类或接口在运行时对类文件中的常量池表的表示。它包含了几种常量,从在编译时已知的数值字面量到必须在运行时解析的方法和字段引用。运行时常量池的作用类似于传统编程语言的符号表,尽管它包含比典型符号表更广泛的数据范围。

每个运行时常量池都从 JVM 的方法区中分配。类或接口的运行时常量池在类或接口被 JVM 创建时构建。

当创建类或接口时,如果运行时常量池的构建需要的内存超过了 JVM 方法区中可用的内存,JVM 将抛出 OutOfMemoryError

本地方法栈(Native Method Stack)

JVM 的实现可能使用传统的栈,俗称为"C stack",以支持本地方法的执行(即用 Java 编程语言之外的语言编写的方法)。本地方法栈也可能被 JVM 指令集的解释器实现所使用,这通常用 C 语言编写。如果JVM实现不能加载本地方法,并且其本身不依赖于传统的栈,则不需要提供本地方法栈。如果提供了本地方法栈,它们通常在每个线程创建时为每个线程分配。

如果线程的计算需要的本地方法栈大小超过了允许的大小,则 JVM 将抛出 StackOverflowError

如果本地方法栈无法获得足够的内存来实现扩展,或者,如果无法获得足够的内存来为新线程创建初始本地方法栈,则 JVM 将抛出 OutOfMemoryError

我们可以根据应用的特定需求,通过修改 JVM 启动参数调整本地方法栈的大小,包括初始值、最小值、最大值。


今天水哥主要讲了 JVM 的内存结构,下次我会讲下 JVM 的内存管理,请继续关注~


如果您在技术探索的旅途中偶遇了这篇文章,水哥感到十分荣幸。感谢您抽出宝贵时间阅读至此。

若您觉得有所收获,不妨点赞、分享,让更多人一同受益。您的支持是我前进的动力。

想了解精粹的软件开发技术、前沿的云计算实践、高效的敏捷管理策略,敬请关注我的公众号(码农水哥:manongshuige),一起探索技术深度,享受敏捷之美。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表