void Method1()
{
byte [] bytearray = new byte[16];
/* some code */
}
void Method2()
{
byte [] bytearray = {0,0};
/* some code */
}
在这两种情况下,假设当Method1和Method2返回时,“bytearray”是垃圾收集的候选者,因为操纵thetearray变量的任何代码都不会在方法本身的结尾处保留引用.
Method2是否通过避免对“新”的呼叫进行更快(或不同的)操作?还是两个以上的实现呢?在这两种情况下,Java编译器或运行时都可以进行优化,以避免针对短暂临时缓冲区的内存分配器造成开销.
解决方法
哪种形式是最好的?几乎总是让你的程序更易读的.
但是有什么实际的区别,不管我们会不会注意到?我们来看一下!
class ArrayTest {
public int[] withNew() {
int[] arr = new int[4];
return arr;
}
public int[] withInitializer() {
int[] arr = {0,0};
return arr;
}
}
我们用javap -c ArrayTest来反汇编:
Compiled from "ArrayTest.java"
class ArrayTest {
Arraytest();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public int[] withNew();
Code:
0: iconst_4
1: newarray int
3: astore_1
4: aload_1
5: areturn
public int[] withInitializer();
Code:
0: iconst_4
1: newarray int
3: dup
4: iconst_0
5: iconst_0
6: iastore
7: dup
8: iconst_1
9: iconst_0
10: iastore
11: dup
12: iconst_2
13: iconst_0
14: iastore
15: dup
16: iconst_3
17: iconst_0
18: iastore
19: astore_1
20: aload_1
21: areturn
}
不,在这种情况下,它们不一样 – 使用初始化器形式会使插槽被单独设置为0,这是因为它们已经被阵列分配置零了,这是无意义的.所以,这基本上等同于:
public int[] withNewAndSettingExplicitly() {
int[] arr = new int[4];
arr[0] = 0;
arr[1] = 0;
arr[2] = 0;
arr[3] = 0;
return arr;
}
虽然编译了另一组字节码,这几乎是相同但不完全相同的:
public int[] withNewAndSettingExplicitly();
Code:
0: iconst_4
1: newarray int
3: astore_1
4: aload_1
5: iconst_0
6: iconst_0
7: iastore
8: aload_1
9: iconst_1
10: iconst_0
11: iastore
12: aload_1
13: iconst_2
14: iconst_0
15: iastore
16: aload_1
17: iconst_3
18: iconst_0
19: iastore
20: aload_1
21: areturn
因此,故事的道德是这样的:如果您希望所有元素设置为0,则使用新的int [size](这可能或可能不会更快)生成较少的字节码,但是您也必须输入较少的imho是一个大胜利).如果要在阵列中直接设置数组中的值,请在代码中使用最好的代码,因为生成的代码将几乎与您选择的形式相同.
现在,回答你的实际问题:
Does Method2 operate any faster (or differently) by avoiding the call to “new”?
正如我们所看到的,新的只是隐藏在初始化器语法之后(寻找newarray op代码).顺便说一句,分配在JVM中是非常便宜的(代代垃圾收集器有这个愉快的副作用).
Or are the two implementations above equivalent?
正如我们所看到的 – 不完全相同,但是不太可能有人会注意到差异.
In either case,can the Java compiler or runtime make an optimization to avoid the overhead of hitting the memory allocator for this short-lived temporary buffer?
再次 – 分配是便宜的,所以不用担心.然而,最近的JVM具有这样一个叫做escape analysis的小功能,这可能导致阵列被分配而不是堆分配.