1

I have the following classes

public void dump(Integer value){
    //do soemthing with value
}
public void dump(Integer[] values){
    //do soemthing with values
}

And I want to call dump(null) , it doesn't matter what I choose to cast to because both work as intended with nulls:

    dump((Integer[]) null);
    dump((Integer) null);
  1. Which one is better to use resource wise (less ram, cpu usage)?
  2. I would think that java would preallocate 4 bytes for a null Integer and 8 bytes for Double, is this true?
  3. What about other (more complicated) objects that are nulled, if no constructor call then how are the nulls stored?
Then Enok
  • 593
  • 5
  • 16
  • 1
    Neither will use more resources at the call site. Which will use less cpu is a function of how the two functions treat the `null` value when received. The `null` is not allocated, so a `(Integer)null` and `(Double)null` use exactly the same amount of heap space ... zero. – AJNeufeld Feb 09 '17 at 23:01
  • 1
    I think your question is mostly answered by http://stackoverflow.com/questions/2430655/java-does-null-variable-require-space-in-memory – azurefrog Feb 09 '17 at 23:02

6 Answers6

8
  1. Which one is better to use resource wise (less ram, cpu usage)?

It won't make any measurable difference.

  1. I would think that java would preallocate 4 bytes for a null Integer and 8 bytes for Double, is this true?

No. Null is null. There is only one format. You are confusing objects and references here. null is a reference. All references are the same size.

What about other (more complicated) objects that are nulled

There is no such thing as 'objects that are nulled'.

if no constructor call then how are the nulls stored?

As nulls.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • objects that are nulled, i meant classes like "TextView textView = null" instead of simple number – Then Enok Feb 09 '17 at 23:15
  • 3
    @ThenEnok Once again you are confusing objects and references. `textView` is a reference. – user207421 Feb 09 '17 at 23:16
  • I understand what you mean, I should have said what 'What about other (more complicated) objects that are have been given null to their variable'' – Then Enok Feb 09 '17 at 23:23
  • 2
    Sigh. Objects don't own variables. Reference variables point to objects, or are null. Setting a reference variable to null doesn't do anything to any object that it may have previously pointed to. – user207421 Feb 09 '17 at 23:24
  • I understand now, thx, it's just I was courious if there was a bigger difference if instead of using Integer I'd use something like the texview above. – Then Enok Feb 09 '17 at 23:27
2

The type of the cast doesn't affect the memory used by null. In a decompiled class:

aconst_null
checkcast     #4                  // class java/lang/Integer
invokevirtual #5                  // Method dump:(Ljava/lang/Integer;)V

vs

aconst_null
checkcast     #6                  // class "[Ljava/lang/Integer;"
invokevirtual #7                  // Method dump:([Ljava/lang/Integer;)

so both are the same in terms of memory usage.

user3486184
  • 2,147
  • 3
  • 26
  • 28
1

I believe they cost equal because you do not have actual objects in both cases (neither Integer object, neither Integer[] object, which definitely have different size in memory).

What you have here is just 4-bytes reference which points to nothing as it null. From this point of view there is no difference between type to which you are casting these null-s.

Andremoniy
  • 34,031
  • 20
  • 135
  • 241
1
  1. No difference.
  2. Nope. Java doesn't allocate any space at all for a null object, since null by definition is a reference to no object at all. No object at all takes no space at all. The reference itself will always be 32 or 64 bits long.
  3. What do you mean by "stored"? A reference variable holds a pointer value, which is always the same size irrespective of the object to which it points. Regardless of the size of the object, even if a reference points to a non-null value, the reference size is always the same no matter what type it references. It is the size of the address. I haven't looked, but I'll bet that the null reference is a special address value such as 0 that points nowhere by definition.

Casting a reference does not change the reference. It still has the exact same value, bit by bit, that it has without the cast.

The only exception to all this is the 32-bit optimization for 64-bit Java. Normally you'd expect all references in 64-bit Java to be, well, 64 bits long. But you can switch on or off the ability to hold references in 32 bits, if certain assumptions about the program hold. But either way, once the JVM decides how wide a reference is, 32 or 64 bits, that will hold true through the program.

So bottom line, no, casting a reference to some other type has no effect on the memory consumed by the reference.

The memory consumed by the object can go to zero if all references to it fall out of scope or become null.

Lew Bloch
  • 3,364
  • 1
  • 16
  • 10
0

All reference values (and both boxed Integer and arrays are reference values) have the same representation, so there is no difference in the call at all. If there is a difference in cost, it would be do to the implementation of the function that is called.

antlersoft
  • 14,636
  • 4
  • 35
  • 55
-2
  1. Which one is better to use resource wise (less ram, cpu usage)?

If you ever need to ask yourself this question, you can always write a simple test.

public class Main {
    private static Integer x = 0;
    private static final int n = 500000000;

    public static void dump(Integer value){
        x += 1;
    }
    public static void dump(Integer[] values){
        x += 1;
    }

    public static void main(String[] args) {
        long t = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            dump((Integer[]) null);
        }
        long array_time = System.currentTimeMillis() - t;
        t = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            dump((Integer) null);
        }
        long int_time = System.currentTimeMillis() - t;
        System.out.println("array_time: " + array_time + " ms");
        System.out.println("int_time: " + int_time + " ms");
    }
}

Output:

array_time: 2578 ms
int_time: 2045 ms

Not a significant difference.

kalanchloe
  • 503
  • 4
  • 12
  • 1
    A better test would be: "javap -c Main" to compare the bytecodes – user3486184 Feb 09 '17 at 23:12
  • 1
    Invalid benchmark. You have failed to warm up the JVM. You have also put a rather complicated operation into `dump()`, which both is unnecessary and reduces the significance of your results. See the bytecode provided in another answer. There is no reason for the times to be even slightly different. – user207421 Feb 09 '17 at 23:18