java - 为什么静态/成员变量比局部变量慢?

标签 java performance bytecode

我看过这个帖子:Speed of if compared to conditional

我自己做了一个类来检查速度

public class Question {
static long startTime;
static long elapsedTime;

static String mStatic;
private String mPublic;

public static void main(String[] args) {
    Question q = new Question();
    q.executeGlobal();
    q.executeStatic();
    q.executeLocal();
}

public void executeLocal() {
    String mLocal;
    startTime = System.nanoTime();
    for (int i = 0; i < 1000000000; i++) {
        mLocal = "";
    }
    elapsedTime = System.nanoTime() - startTime;
    System.out.println("Type Local: " + elapsedTime + " ns");

}

public void executeGlobal() {
    startTime = System.nanoTime();
    for (int i = 0; i < 1000000000; i++) {
        mPublic = "";
    }
    elapsedTime = System.nanoTime() - startTime;
    System.out.println("Type Global: " + elapsedTime + " ns");

}

public void executeStatic() {
    startTime = System.nanoTime();
    for (int i = 0; i < 1000000000; i++) {
        mStatic = "";
    }
    elapsedTime = System.nanoTime() - startTime;
    System.out.println("Type Static: " + elapsedTime + " ns");
}

}

结果:

Type Global: 45693028 ns
Type Static: 43853723 ns
Type Local: 2057505 ns

@Rod_algonquin 在回答中回答说这是因为静态变量的 getstatic/putstatic 字节码和 getfield/putfield 成员变量的字节码,它通过位移和一些加法计算。

起初我以为只有 Objects 导致了这个,但是在尝试引用基元时结果是相同的 local variable 仍然更快 .

为什么局部变量更快?除了字节码解释。

最佳答案

一般来说,jvm使用三种不同的内存段

  1. 堆 - 包含运行时创建的所有对象,仅对象加上 它们的对象属性(实例变量)
  2. 堆栈 - 包含局部变量和引用变量(保存堆中对象地址的变量)
  3. 代码段——加载时实际编译的Java字节码所在的段

堆栈值仅存在于创建它们的函数范围内。一旦返回,它们将被丢弃。

然而,堆值存在于堆上。它们在某个时间点创建,并在另一个时间点销毁(通过 GC 或手动)。 Java 仅将原语存储在堆栈中。这使堆栈保持较小并有助于保持单个堆栈帧较小,从而允许更多的嵌套调用。对象是在堆上创建的,只有引用(这又是原语)在堆栈上传递。

Java 使用三种不同类型的变量

  • 静态变量:- 类变量称为静态变量。 每个 JVM 每个类只出现一次类变量 装载机。当一个类被加载时,类变量(又名静态 变量)被初始化。它们位于类(字节码)的位置 驻留,在代码段
  • 实例变量:- 实例变量是非静态的,并且有 每个类实例中出现一次实例变量(即 每个对象)。也称为成员变量或字段。
  • 局部变量:局部变量的范围比实例小 变量。局部变量的生命周期由 执行路径

与代码段相比,访问堆栈相对更快(尽管它纯粹是特定于 JVM 实现的),因此有神论地访问局部变量比全局变量更快。

详情可以查看http://blog.jamesdbloom.com/JVMInternals.htmlit-haggar_bytecode

还有一篇文章分析了static vs local variable的性能

关于java - 为什么静态/成员变量比局部变量慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25073124/

相关文章:

java - 如何获取java MethodDeclaration对应的Byte code

java - 如何在不使用工具的情况下将字节码注入(inject)到已编译的java程序中?

java - Android getOrientation 问题 - 沿轴镜像值

java - 无法将项目列表发送到后端以从列表中删除

java - 使用 [^a-zA-Z] 正则表达式替换单词时出现问题

java - 消除重复条目的最有效方法

java - 使用 Java 在 Google Drive SDK 中搜索文件(有条件)

c# - F# 中的模式匹配比 C# 中的 If else/switch 慢得多吗?

python - 如何分析 Python 脚本?

java - Scala 的多个参数列表如何编码为 JVM 字节码