Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object vs byte[0] as lock

I commented earlier on this question ("Why java.lang.Object is not abstract?") stating that I'd heard that using a byte[0] as a lock was slightly more efficient than using an java.lang.Object. I'm sure I've read this somewhere but I can't recall where: Does anyone know if this is actually true?

I suspect it's due to the instantiation of byte[0] requiring slightly less byte code than Object, although it was pointed out that byte[0] requires additional storage in order to store the length field and so it sounds like this might negate any benefit.

like image 494
Adamski Avatar asked Jan 22 '10 20:01

Adamski


People also ask

Can you lock on object in Java?

Object Lock in JavaWhenever an object is created, an object lock also gets created with it. Monitor is an object which is used as a mutual exclusive lock. Monitor can be owned by one thread only. To execute any block, a thread needs to acquire an object lock associated with that object.

Is a byte array an object?

A bytearray is always created using the bytearray() built-in function. bytearray objects are mutable.

What is lock in java thread?

A lock may be a tool for controlling access to a shared resource by multiple threads. Commonly, a lock provides exclusive access to a shared resource: just one thread at a time can acquire the lock and everyone accesses to the shared resource requires that the lock be acquired first.

What is Byte array in c#?

With byte arrays, we can store binary data. This data may be part of a data file, image file, compressed file or downloaded server response. Array info. With byte arrays, we have an ideal representation of this data. The byte array type allows us to store low-level representations.


3 Answers

Using java.lang.instrument.Instrumentation to check the sizes:
Object uses 8 bytes, byte[0] needs 16 bytes. (not sure if the size is in bytes, not documented).

I also got the time to create an Object and a byte[0] (2 times): Object is the winner.

(all tests run on a DELL laptop, Intel 2GHz, Windos XP)

Using the client VM

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]

Using the server VM

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]

I will stay with new Object(), not only because of readability :-)

The Code

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();
    }
  }
}

Timer* uses ThreadMXBean to get the times.

*Timer is a class I made for timming, it is not one of the Java Timer's.

like image 78
user85421 Avatar answered Oct 27 '22 01:10

user85421


I got curious enough to test it. Sourcecode:

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

    public static byte[] returnArray(){
        return new byte[0];
    }
}

Bytecode:

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

So you're right in that the byte code is shorter for arrays, because array creation has its own JVM opcode. But what does that mean? Nothing, really. It's a virtual machine, so there's absolutely no guarantee that fewer bytecode instructions mean less work for the actual physical CPU. We could start profiling of course, but that would be quite pointless. If there is a difference at all, no matter which way, it will never ever matter. Object creation is incredibly fast nowadays. You'd probably have to start using long for your loop index before you can even measure the total time.

like image 38
Michael Borgwardt Avatar answered Oct 27 '22 01:10

Michael Borgwardt


According to the Java Language Spec, "all class and array types inherit the methods of class Object", so I don't know how byte[0] could manage to be more efficient.

That seems to be true for the first edition of the spec as well: "The superclass of an array type is considered to be Object".

like image 43
Nathan Hughes Avatar answered Oct 27 '22 01:10

Nathan Hughes