Array handling by Java Virtual Machine

giudaballerino :

I have a silly question for you all. Given the following Java Code

public void funct(String a) {
    byte[] bytearr;

    bytearr = new byte[a.getBytes().length];
    bytearr = a.getBytes();
}

Does the new call change anything? In particular, is the code processed in a different way from

public void funct(String a) {
    byte[] bytearr;

    bytearr = a.getBytes();
}

I am asking because, when executed, both present the same results and I can't get if

  • They're different (in the first case space is allocated and filled while in the second it's more like a "pointer assignation").
  • They're the same and I overthink alot.
  • Second one is wrong but JVM is smarter than me and fixes it.

More in general, any suggestion to observe memory allocations/magic behaviour behind JVM would be very appreciated.

Thanks!

Andronicus :

They are different, let us take a look at the bytecode:

1. version:

   L0
    LINENUMBER 9 L0
    ALOAD 0
    ICONST_0
    AALOAD
    INVOKEVIRTUAL java/lang/String.getBytes ()[B
    ARRAYLENGTH
    NEWARRAY T_BYTE
    ASTORE 1
   L1
    LINENUMBER 10 L1
    ALOAD 0
    ICONST_0
    AALOAD
    INVOKEVIRTUAL java/lang/String.getBytes ()[B
    ASTORE 1
   L2
    LINENUMBER 11 L2
    RETURN
   L3
    LOCALVARIABLE args [Ljava/lang/String; L0 L3 0
    LOCALVARIABLE bytearr [B L1 L3 1
    MAXSTACK = 2
    MAXLOCALS = 2

2. version:

   L0
    LINENUMBER 9 L0
    ALOAD 0
    ICONST_0
    AALOAD
    INVOKEVIRTUAL java/lang/String.getBytes ()[B
    ASTORE 1
   L1
    LINENUMBER 10 L1
    RETURN
   L2
    LOCALVARIABLE args [Ljava/lang/String; L0 L2 0
    LOCALVARIABLE bytearr [B L1 L2 1
    MAXSTACK = 2
    MAXLOCALS = 2

The difference is in those instructions comming from the extra line:

LINENUMBER 9 L0
ALOAD 0
ICONST_0
AALOAD
INVOKEVIRTUAL java/lang/String.getBytes ()[B
ARRAYLENGTH
NEWARRAY T_BYTE
ASTORE 1

This introduces additional overhead (getBytes being called twice, more instructions). By invoking bytearr = a.getBytes() jvm already handles the size of the array being stored.

But since the first initialization is redundant, it will probably be optimized by the compiler at some point (after enough runs). Still, there is no need for additional instructions and less readable code.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=418971&siteId=1