0 java
class Sample {
int a;
public void abcx() {
for (int i = 0; i < 5; i++) {
if (i % 2 == 0) {
int b = i;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
多久b分配一次?
请看看nhahtdh的回答.这很好,因为它引用了JLS的相关部分.
我不删除这个答案,因为我希望它能为您提供一些提示,以便您自己解决未来问题的答案(或至少是好的猜测).它还可能为您的示例代码提供一些其他说明.
首先:如果谈到"在XYZ情况下Java会做什么",你应该经常问"我的JVM在XYZ情况下做了什么".如果您想回答有关Java本身的问题,您应该能够参考Java语言规范.
编辑:有关此参考,请参阅nhahtdh答案.
我猜你可以做的最好的猜测是Java Bytecode.现在加载对象/数据结构/基元类型和分配一个类型之间存在差异.
分配对象意味着您可以为其提供一些可以存储的空间.它只是一个占位符.要加载aload_0意味着对象引用被推送到操作数堆栈上.下一个操作将从操作数堆栈中获取其操作数.
javac Sample.java
javap -c Sample.class
Run Code Online (Sandbox Code Playgroud)
给你Java字节码:
Compiled from "Sample.java"
class Sample {
int a;
Sample();
Code:
0: aload_0 // load int a
1: invokespecial #1 // Method java/lang/Object."<init>":()V (every class is a child class of Object)
4: return
public void abcx();
Code:
0: iconst_0 // get 0 on stack
1: istore_1 // store 0 to variable 1 (int i=0)
2: iload_1 // load 0 from variable 1 (load 0 from i)
3: iconst_5 // load 5 from
4: if_icmpge 21 // i<5 (21 means: jump to line 21 if i >= 5)
7: iload_1 // load i
8: iconst_2 // load 2
9: irem // i%2
10: ifne 15 // if(i%2!=0) jump to line 15
13: iload_1 // load i
14: istore_2 // b=i
15: iinc 1, 1 // i++
18: goto 2 // back to loop condition
21: return
}
Run Code Online (Sandbox Code Playgroud)
我不确定答案是否正确.我猜用户Budda可能是对的:
编辑:不,Budda错了.但让我们解释为什么这是一个很好的猜测.
当i为0时分配一次,然后当i为2时再分配,当i为4时分配.因此总共为3.
一旦}关闭,范围b就结束了.因此它应该被垃圾收集器"删除",因为b它没有参考.但是你必须考虑原始数据类型不在堆上,只有堆由垃圾收集器(源)管理.
当您查看上面的字节代码时,您可能会注意到b仅在一行(istore_2)中更改.所以你可能想看看进程的内存布局.
我不确定Java程序是否也适用,但x86中的进程也是如此.进程在内存中看起来像这样:
来源:我的博客 :-)这是一个操作系统类的分配.
您可以看到原始数据类型在内存布局中有自己的部分.所以我猜它在加载类时会被分配一次.但我不能给你这个猜测的来源,我不确定.
编辑:另请参阅Java虚拟机的体系结构.
| 归档时间: |
|
| 查看次数: |
168 次 |
| 最近记录: |