1. 概述
在我们的日常工作中,我们往往并不关心JVM内部的内存分配情况。
然而, 了解 JVM 内存模型的基础知识对于性能优化和提高代码质量非常有用 。
在本文中,我们将探讨静态方法和成员的 JVM 存储。
2. JVM的内存分类
在深入研究静态成员的内存分配之前,我们必须刷新对 JVM 内存结构的理解。
2.1.堆内存
堆内存是所有 JVM 线程共享的运行时数据区域,用于为所有类实例和数组分配内存。
Java 将堆内存分为两类——年轻代和老年代。
JVM内部将年轻代分为Eden区和Survivor区。同样,Tenured Space 是老一代的正式名称。
堆内存中对象的生命周期由称为垃圾收集器的自动内存管理系统管理。
因此, 垃圾收集器可以自动释放对象或将其移动到堆内存的各个部分 (年轻代到老年代)。
2.2.非堆内存
非堆内存主要由 方法区组成,用于存储类结构、字段、方法数据以及方法/构造函数的代码 。
与堆内存类似,所有 JVM 线程都可以访问方法区。
方法区,也称为永久代(PermGen),逻辑上被认为是堆内存的一部分,尽管 JVM 的更简单的实现可能选择不对其进行垃圾收集。
然而, Java 8 删除了 PermGen 空间并引入了一个名为 Metaspace 的新本机内存空间 。
2.3.高速缓存存储器
JVM预留缓存区域用于本地代码的编译和存储,例如JVM内部结构和JIT编译器产生的本地代码。
3. Java 8之前的静态成员存储
在 Java 8 之前, PermGen 存储静态成员 ,如静态方法和静态变量。此外,PermGen 还存储内部字符串。
换句话说,PermGen 空间存储变量及其技术值,可以是原语或引用。
4. Java 8 及更高版本的静态成员存储
正如我们已经讨论过的, Java 8 中 PermGen 空间被 Metaspace 取代,导致静态成员的内存分配发生变化。
从Java 8开始,元空间只存储类元数据, 堆内存保存静态成员 。此外,堆内存还为内部字符串提供存储。
5. 结论
在这篇短文中,我们探讨了静态成员的 JVM 存储。
首先,我们快速浏览了 JVM 的内存模型。然后,我们讨论了 Java 8 之前和之后的 JVM 静态成员存储。
简而言之,我们知道 静态成员在 Java 8 之前是 PermGen 的一部分 。然而, 从 Java 8 开始,它们是堆内存的一部分 。