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月前
|
存储 算法 Java
jvm性能优化(一)-基于JDK1.8
jvm性能优化(一)-基于JDK1.8
|
1月前
|
缓存 Java Maven
java: 警告: 源发行版 11 需要目标发行版 11 无效的目标发行版: 11 jdk版本不符,项目jdk版本为其他版本
如何解决Java项目中因JDK版本不匹配导致的编译错误,包括修改`pom.xml`文件、调整项目结构、设置Maven和JDK版本,以及清理缓存和重启IDEA。
48 1
java: 警告: 源发行版 11 需要目标发行版 11 无效的目标发行版: 11 jdk版本不符,项目jdk版本为其他版本
|
1月前
|
Java 关系型数据库 MySQL
【编程基础知识】Eclipse连接MySQL 8.0时的JDK版本和驱动问题全解析
本文详细解析了在使用Eclipse连接MySQL 8.0时常见的JDK版本不兼容、驱动类错误和时区设置问题,并提供了清晰的解决方案。通过正确配置JDK版本、选择合适的驱动类和设置时区,确保Java应用能够顺利连接MySQL 8.0。
140 1
|
1月前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
53 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
1月前
|
Java 关系型数据库 开发工具
idea创建不了spring2.X版本,无法使用JDK8,最低支持JDK17 , 如何用idea创建spring2.X版本,使用JDK8解决方案
本文提供了解决方案,如何在IDEA中创建Spring 2.X版本的项目并使用JDK8,尽管Spring 2.X已停止维护且IDEA不再直接支持,通过修改pom.xml或使用阿里云的国内源来创建项目。
73 0
idea创建不了spring2.X版本,无法使用JDK8,最低支持JDK17 , 如何用idea创建spring2.X版本,使用JDK8解决方案
|
1月前
|
Oracle Java 关系型数据库
jdk17安装全方位手把手安装教程 / 已有jdk8了,安装JDK17后如何配置环境变量 / 多个不同版本的JDK,如何配置环境变量?
本文提供了详细的JDK 17安装教程,包括下载、安装、配置环境变量的步骤,并解释了在已有其他版本JDK的情况下如何管理多个JDK环境。
715 0
|
3月前
|
Java 开发工具
开发工具系列 之 同一个电脑上安装多个版本的JDK
这篇文章介绍了如何在一台电脑上安装和配置多个版本的JDK,包括从官网下载所需JDK、安装过程、配置环境变量以及如何查看和切换当前使用的JDK版本,并提到了如果IDEA和JDK版本不兼容时的解决方法。
开发工具系列 之 同一个电脑上安装多个版本的JDK
|
3月前
|
Java API
JDK8到JDK25版本升级的新特性问题之使用Collectors.teeing()来计算一个列表中学生的平均分和总分如何操作
JDK8到JDK25版本升级的新特性问题之使用Collectors.teeing()来计算一个列表中学生的平均分和总分如何操作
|
3月前
|
Java API Apache
JDK8到JDK24版本升级的新特性问题之在Java中,HttpURLConnection有什么局限性,如何解决
JDK8到JDK24版本升级的新特性问题之在Java中,HttpURLConnection有什么局限性,如何解决
|
3月前
|
Oracle Java 关系型数据库
JDK8到JDK29版本升级的新特性问题之未来JDK的升级是否会成为必然趋势,如何理解
JDK8到JDK29版本升级的新特性问题之未来JDK的升级是否会成为必然趋势,如何理解