对象vs字节[0]为锁

Ada*_*ski 4 java multithreading synchronization locking synchronized

我之前评论过这个问题("为什么java.lang.Object不是抽象的?")说我听说使用byte[0]锁定比使用锁定更有效java.lang.Object.我确定我已经在某个地方读过这篇文章,但我不记得在哪里:有谁知道这是否真的如此?

我怀疑这是由于实例化byte[0]需要的字节码略少Object,尽管有人指出byte[0]需要额外的存储来存储长度字段,所以听起来这可能会否定任何好处.

use*_*421 14

使用java.lang.instrument.Instrumentation检查大小:
Object使用8个字节,byte [0]需要16个字节.(不确定大小是否以字节为单位,未记录).

我也有时间创建一个Object和一个byte [0](2次):Object是胜利者.

(所有测试均在戴尔笔记本电脑,英特尔2GHz,Windos XP上运行)

使用clientVM

java version "1.6.0_16"
Java(TM) SE Runtime Environment (build 1.6.0_16-b01)
Java HotSpot(TM) Client VM (build 14.2-b01, mixed mode)

an implementation-specific approximation of the amount of storage
Object  = 8
byte[0] = 16

time to create 1000000000 instances
Object:  elapsed=11,140   cpu=9,766    user=9,703    [seconds]
byte[0]: elapsed=18,248   cpu=15,672   user=15,594   [seconds]

time to create 1000000000 instances
Object:  elapsed=11,135   cpu=9,828    user=9,750    [seconds]
byte[0]: elapsed=18,271   cpu=15,547   user=15,469   [seconds]
Run Code Online (Sandbox Code Playgroud)

使用serverVM

java version "1.6.0_16"
Java(TM) SE Runtime Environment (build 1.6.0_16-b01)
Java HotSpot(TM) Server VM (build 14.2-b01, mixed mode)

an implementation-specific approximation of the amount of storage
Object  = 8
byte[0] = 16

time to create 1000000000 instances
Object:  elapsed=8,441    cpu=7,156    user=7,125    [seconds]
byte[0]: elapsed=11,237   cpu=8,609    user=8,500    [seconds]

time to create 1000000000 instances
Object:  elapsed=8,501    cpu=7,234    user=7,156    [seconds]
byte[0]: elapsed=11,023   cpu=8,688    user=8,641    [seconds]
Run Code Online (Sandbox Code Playgroud)

我会留下来new Object(),不仅仅是因为可读性:-)

代码

public class ObjectArrayCompare {

  private static Object o;

  public static void main(String[] args) {
    Instrumentation instr = InstrumentationAgent.getInstrumentation();
    if (instr == null) {
        System.err.println("No Instrumentation, use \"-javaagent:Instrumentation.jar\"");
        return;
    }
    System.out.println();
    System.out.println("an implementation-specific approximation of the amount of storage");
    System.out.println("Object  = " + instr.getObjectSize(new Object()));
    System.out.println("byte[0] = " + instr.getObjectSize(new byte[0]));
    System.out.println();

    final int MAX = (int) 1.0e9;
    Timer timer;
    Times times;

    for (int j = 0; j < 2; j++) {
      System.out.println("time to create " + MAX + " instances"); 
      timer = new Timer();
      for (int i = 0; i < MAX; i++) {
        o = new Object();
      }
      times = timer.times();
      System.out.println("Object:  " + times);

      timer = new Timer();
      for (int i = 0; i < MAX; i++) {
        o = new byte[0];
      }
      times = timer.times();
      System.out.println("byte[0]: " + times);

      System.out.println();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Timer *用于ThreadMXBean获取时间.

* Timer是我修改的类,它不是 Java Timer的一个.


Mic*_*rdt 13

我很好奇地测试它.源代码:

public class Test {
    public static Object returnObject() {
        return new Object();
    }

    public static byte[] returnArray(){
        return new byte[0];
    }
}
Run Code Online (Sandbox Code Playgroud)

字节码:

public static java.lang.Object returnObject();
  Code:
   0:   new     #2; //class java/lang/Object
   3:   dup
   4:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   7:   areturn

public static byte[] returnArray();
  Code:
   0:   iconst_0
   1:   newarray byte
   3:   areturn
Run Code Online (Sandbox Code Playgroud)

所以你是对的,因为数组的字节代码更短,因为数组创建有自己的JVM操作码.但是,这是什么意思?真的没什么.它是一个虚拟机,因此绝对无法保证较少的字节码指令意味着实际物理CPU的工作量减少.我们当然可以开始进行剖析,但那将毫无意义.如果存在差异,无论采用哪种方式,都不会有任何影响.如今,对象创建速度非常快.您可能必须先开始使用long循环索引,然后才能测量总时间.


Nat*_*hes 5

根据 Java语言规范,"所有类和数组类型都继承了Object类的方法",所以我不知道byte [0]如何能够提高效率.

对于规范的第一版似乎也是如此:"数组类型的超类被认为是对象".