JVM-不同jdk版本静态变量存储位置

简介: JVM-不同jdk版本静态变量存储位置

1. 什么是 JDK?

JDK(Java Development Kit)是一个软件开发工具包,它提供了开发 Java 应用程序所需的所有工具、编译器和库的集合。

2. 静态变量是什么?

静态变量,也被称为类变量,是在类的定义中使用 static 关键字声明的变量。静态变量存储在内存中的数据区域,与其他全局变量相似,因此它们的生命周期和应用程序的生命周期相同。在一个类中所有的实例都可以访问和更改静态变量,它们被所有类实例共享,而不是每个实例都有一份属于自己的变量副本。

3. 不同 JDK 版本静态变量存储位置的原理

不同 JDK 版本使用不同的 JVM 实现,并且不同的操作系统上 JVM 的行为也会有所不同。使用 JVM 内存模型概念来解释,不同的版本和实现 JVM 的具体方式也不同。对于静态变量,每个 JVM 实现可能会将它们存储在不同的位置。

3.1 早期 JDK 环境

在早期版本的 JDK 中,JVM 使用了方法区来存储静态变量。在 Java 6 及之前的版本中,方法区本质上是一个永久代(PermGen),它又被称为静态存储区,它是 JVM 内存模型中的一个区域,它负责存储类内的常量、静态变量、类的信息和方法信息等。这个区域的生命周期与 JVM 的生命周期相同,它的大小可以通过启动参数配置。静态变量存储在该区域的某个位置,以供所有类实例访问。

3.2 JDK 8 及之后版本

在 Java 8 及之后的版本中,永久代被 Metaspace 所替代,而 Metaspace 已被放置在堆中。所以,在这些版本中,静态变量被存储在堆中。Metaspace 是 JVM 中的一块内存区域,它用于存储类信息和 JIT 编译器生成的代码,其大小也可以通过启动参数来设置。在较新的版本中,JVM 已经使用了一种叫做“CompressedClassSpace”的技术来节省 Metaspace 的内存使用。

4. 静态变量存储位置的实验

这里给出一个简单的实验来验证不同 JDK 版本静态变量存储位置不同的事实。

在 Java 6 及之前的版本中,我们可以通过下面的代码来验证静态变量存储在方法区中:

public class StaticVariable {
    private static int count = 0;
    public StaticVariable() {
        count++;
    }
    public static int getCount() {
        return count;
    }
}

下面是验证代码:

for(int i = 0; i < 10; i++) {
   StaticVariable sv = new StaticVariable();
}
System.out.println("StaticVariable Count: " + StaticVariable.getCount());

由于该版本的 JVM 使用的是 PermGen 作为方法区,在执行上述代码后,我们可以在输出信息中看到静态变量存储到了方法区:

StaticVariable Count: 10

在 Java 7 及之后的版本中,我们可以通过下面的代码来验证静态变量存储在堆中:

public class StaticVariable {
    private static int count = 0;
    public StaticVariable() {
        count++;
    }
    public static int getCount() {
        return count;
    }
}

下面是验证代码:

for(int i = 0; i < 10; i++) {
   StaticVariable sv = new StaticVariable();
}
System.out.println("StaticVariable Count: " + StaticVariable.getCount());

由于该版本的 JVM 使用的是 Metaspace 作为堆中的一部分,在执行上述代码后,我们可以在输出信息中看到静态变量存储在堆中:

StaticVariable Count: 10

5. 总结

我们从以上可以看出,JDK 版本不同,JVM 对静态变量的管理方式不同,因此静态变量所存储的位置也不同。在 Java 6 之前,静态变量存储在 JVM 的方法区中,而在 Java 7 之后的版本中,静态变量存储在 JVM 的堆中。来自同一 JDK 版本的 JVM 实现将在存储静态变量的方式上保持一致。了解 JVM 对 Java 中不同类型的变量的处理方式有助于我们编写更健壮、更高效的 Java 代码。


相关文章
|
2月前
|
安全 Oracle Java
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
222 0
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
|
5月前
|
Java
IDEA修改JDK版本
在IDEA中修改项目JDK版本的方法如下:1. 右键点击项目;2. 选择“Open Module Settings”,如图所示;3. 在弹出窗口中配置自定义的JDK路径。通过以上步骤,可轻松更改项目所使用的JDK版本,满足不同开发环境的需求。
1196 65
|
2月前
|
Ubuntu Java Android开发
在Ubuntu 18.04上安装与JDK 8兼容的Eclipse版本的步骤。
安装过程结束后,您就可以开始使用Eclipse来开发您的Java项目了,并且确保它与JDK 8兼容无误。这个过程涉及的是一个基本的安装流程,针对使用Java 8的用户,Eclipse的其他配置和插件安装根据个人开发环境和需求来定制。
196 0
|
4月前
|
存储 算法 Java
JvM JDK JRE 三者区别与联系详解
本文深入解析了Java编程中的三个核心概念:JVM(Java虚拟机)、JDK(Java开发工具包)和JRE(Java运行环境)。JVM是执行Java字节码的虚拟计算机,实现“一次编译,到处运行”;JDK包含JRE及开发工具,用于编写和调试Java程序;JRE负责运行已编译的Java程序。文章详细阐述了它们的功能、组成及应用场景,并通过实例说明其在实际开发中的作用,帮助开发者理解三者联系与区别,提升开发效率与问题解决能力。适合Java初学者及进阶开发者学习参考。
676 3
|
4月前
|
监控 Oracle Java
JVM JDK JRE 使用指南及组件封装方法详解
本指南全面介绍了JVM、JDK、JRE的使用方法与Java组件封装技巧。内容涵盖JDK安装配置、JRE使用、JVM参数调优(如堆内存设置和垃圾回收器选择),以及类、包的封装实践。通过示例展示工具类与数据访问组件的封装方法,并讲解JAR包创建与发布流程。此外,还提供了常见问题解决方案,如内存溢出处理和依赖冲突管理。帮助开发者掌握高效、规范的Java开发技能,提升代码复用性和可维护性。附带面试资料供进一步学习。
187 0
|
6月前
|
Java API 开发工具
Android cmdline-tools版本与最小JDK的关系
总的来说,Android的命令行工具和JDK之间的关系就像是一场舞会,两者需要彼此配合,才能共同创造出美妙的舞蹈。如果选择了不合适的舞伴(即不兼容的版本),可能会导致舞蹈中的步伐混乱,甚至无法完成舞蹈。而即使选择了合适的舞伴,也需要考虑舞伴的舞蹈技巧(即性能和稳定性),才能确保舞蹈的完美表现。因此,选择合适的Android命令行工具和JDK版本,是每一个Android开发者都需要面对的重要决定。
206 13
|
存储 算法 Java
jvm性能优化(一)-基于JDK1.8
jvm性能优化(一)-基于JDK1.8
|
11月前
|
Oracle 安全 Java
深入理解Java生态:JDK与JVM的区分与协作
Java作为一种广泛使用的编程语言,其生态中有两个核心组件:JDK(Java Development Kit)和JVM(Java Virtual Machine)。本文将深入探讨这两个组件的区别、联系以及它们在Java开发和运行中的作用。
374 1
|
11月前
|
Java 编译器 API
深入解析:JDK与JVM的区别及联系
在Java开发和运行环境中,JDK(Java Development Kit)和JVM(Java Virtual Machine)是两个核心概念,它们在Java程序的开发、编译和运行过程中扮演着不同的角色。本文将深入解析JDK与JVM的区别及其内在联系,为Java开发者提供清晰的技术干货。
206 1
|
缓存 Java Maven
java: 警告: 源发行版 11 需要目标发行版 11 无效的目标发行版: 11 jdk版本不符,项目jdk版本为其他版本
如何解决Java项目中因JDK版本不匹配导致的编译错误,包括修改`pom.xml`文件、调整项目结构、设置Maven和JDK版本,以及清理缓存和重启IDEA。
537 2
java: 警告: 源发行版 11 需要目标发行版 11 无效的目标发行版: 11 jdk版本不符,项目jdk版本为其他版本