java - 临时变量的范围——Eclipse/编译器是否优化?

标签 java android scope

首先,我请那些有“过早优化”恐惧症的人放过我:我不想优化任何东西,我只是好奇

我阅读/观察到两件事,包括在 stackoverflow 上(现在找不到链接):

  • 对于方法调用,所有 局部变量的内存都保留在方法的“开头”,即即使是在较低级别范围内声明的变量(我知道这是糟糕的措辞科学上,例如忽略调用机制的工作原理等,但我希望这一点很清楚)。显然,运行程序不存在作用域,它们仅存在于源代码级别,以提高可读性、可维护性、代码结构,告诉编译器我们的 Intent (例如,提供优化提示,见下文)。
  • 在尽可能小的范围内(即仍然需要它们的最高级别)声明变量的优点之一是“编译器可以重用内存其他临时变量(在其他 block 中)”。这对我来说听起来很清楚且合乎逻辑。

我想知道编译器/JIT/任何东西实际上可以优化什么,不能优化什么。

这里是下面的方法(假设变量确实被使用,所以他们不能因为这个原因被优化掉):

// The method does many (useful) things, but these were cut here
public void myMethod() {
    int var1 = 1;
    ... // do work
    if (something) {
        int var2 = 2;
        int var3 = 3;
        ... // do work
    }
    int var4 = 4;
    int var5 = 5;
    ... // do work
}

1.) 编译器是否能够检测到 var2var3 的空间可以重新用于 var4var5 ?我不记得在反汇编的字节码中看到过这样的东西。

2.) 上面的代码方法是否等同于方法的结尾也放入{}的情况?

public void myMethod() {
    int var1 = 1;
    ... // do work
    if (something) {
        int var2 = 2;
        int var3 = 3;
        ... // do work
    }
    {
        int var4 = 4;
        int var5 = 5;
        ... // do work
    }
}

最后,我们来看一个更简单的案例:

public void myMethod() {
    int var1 = 1;
    ... // do work, and then don't refer to var1 any more

    int var4 = 4;
    int var5 = 5;
    ... // do work      
}

3.) 在这种情况下,var1 内存是否可以重新用于var4(或var5)? IE。在这种情况下,该方法为两个 局部int 变量提供内存就足够了,而不是三个。

(我知道从理论上讲,这些对于编译器来说是显而易见的情况,但有时我会忽略一些事情,例如为什么编译器不能做或假设任何事情。)

最佳答案

我可以代表真正 CPU 的编译器,我不确定 JVM 编译器,而且我认为在编译级别代码没有像您想象的那样优化(Java 平台根本不太关心您可以想象的内存占用空间)。

对于真正的编译器,这些场景实际上经常被优化。这不是在高级语言级别上完成的,而是在较低的中间级别上完成的,例如 RTL。等级。一切都是为了寄存器分配或堆栈分配而进行的,并且通过计算函数内部变量的生存集来工作。

这意味着当代码被编译时,所有的东西都被翻译成 RTL,假设有任意数量的临时寄存器,然后对于每个临时寄存器,它的 Activity 状态是通过所谓的 live variable analysis 计算的。 .这只是优化此类事情的方法之一。

例如

  • var1 有效范围是从指令 1 到 10
  • var2 有效范围是从指令 5 到 17
  • var3 有效范围是从指令 3 到 25
  • 等等

这是在将代码拆分为不包含跳转或标签的 block 之后完成的,以便您确定任何指定 block 内的流程。

在这个计算之后,您可以很容易地看到哪些变量在大多数时间是需要的,哪些变得无用并且可以释放它们的保留空间等等。这样做是为了让您能够将尽可能多的变量装入寄存器并大量优化汇编代码。

我个人认为 javac 不会做任何这些事情(即使因为 JVM 是基于堆栈的,所以这只会破坏对象的内存分配,而现在不需要),但我只是猜测.

关于java - 临时变量的范围——Eclipse/编译器是否优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14168463/

相关文章:

javascript - `this` 内部 React 组件生命周期 Hook 的范围问题

javascript - 网络应用程序 : modules speaking with each others

java - 在两台 Linux 系统计算机之间从 Java 调用 linux shell 命令

java - 以编程方式创建时,Primefaces Datatable sortField null 和过滤器映射 {}

java - Spring Controller 请求资源中点的映射问题

来自通知栏 Intent 的 Android 调用方法

Android获取当前歌曲播放和歌曲更改事件,如Musixmatch

java - 如何反转链表实现的顺序?

javascript - Twitter Bootstrap 下拉菜单在平板电脑上无法点击

php - 如何访问 PHPUnit 3.4.9 中的全局变量?