Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do specialized Optional types (OptionalInt, OptionalDouble, etc) perform a heap allocation?

Tags:

java

java-8

Does calling functions that return specialized Optional types come at the cost of increased GC pressure when used in a hot code path, as opposed to returning a primitive value to indicate absence (Integer.MIN_VALUE, for example)?

Edit

The reason I don't just assume they would perform a heap allocation like any other class is that Optional, et al, are "value-based classes", which would seem to imply that they may behave differently than traditional classes behind the scenes.

like image 629
w.brian Avatar asked Oct 21 '15 20:10

w.brian


2 Answers

Does calling functions that return specialized Optional types come at the cost of increased GC pressure when used in a hot code path

It depends™. In general the Optional types are just regular objects, and thus heap allocated. But under specific circumstances the JIT compilers may decompose them into their fields (i.e. the value they hold) and put them on the stack.

This happens if escape analysis can determine that the object does not globally escape onto the heap.

There also seem to be additional, experimental optimizations hidden behind flags (-XX:+AggressiveUnboxing, part of -XX:+AggressiveOpts). As I understand it they can break the identity guarantee for Integer.valueOf(int) and thus is not fully spec-compliant.

A tangent: The experimental/research Graal compiler even goes one step further and has partial escape analysis which can defer allocation to those code paths where objects do escape while leaving them scalar-decomposed on the stack when they don't. This is not yet part of regular VMs and mostly used by non-java languages running on the JVM, such as JRuby and Nashorn.

Since all of these things are a runtime optimization there is no guarantee that this will happen. So you will have to measure the effects or track compiler decisions with diagnostic flags.

The reason I don't just assume they would perform a heap allocation like any other class is that Optional, et al, are "value-based classes"

I think at the moment those properties are simply meant to ensure that the objects are immutable and thread-safe. I don't know whether any optimization beyond EA makes use of the interchangeability properties.

I suspect that the specification language is mostly meant to provide forward-compatibility to proper value-types when they eventually arrive in the Java as part of project valhalla.

Following those rules also makes things easier for escape analysis/stack allocation.

like image 115
the8472 Avatar answered Oct 29 '22 19:10

the8472


Yes.

These classes extend Object and therefore are reference types. They will take up heap space similar to if you used previously-available wrapper classes like Integer.

Furthermore, these types encourage the use of lambda expressions, which themselves create new instances of anonymous types. Depending on what values the lambdas "close over", you may end up with those objects referencing other objects as well, which would have some influence on GC.

So in places where you would want to avoid instantiating instances of classes, boxing/unboxing, and such for performance reasons, you'll still want to avoid these optional types.

Update

Java 8 introduces the concept of value-based classes as a hopeful stepping-stone to Java 10's "value types."

InfoQ: Let's talk a bit about the possibility of Optional as a proto-value type.

Goetz: There was potentially some slight optimism about the idea of migrating a Java 8 reference type to a Java 10 value type. Basically, we've laid the groundwork, by indicating that developers must not rely upon certain properties (such as identity checks) necessarily being true for types that may become value types in the future. Whether this migration proves to be doable in practice remains to be seen.

http://www.infoq.com/articles/Java-9-and-Beyond-Goetz-Rose-Interview

So as of Java 8, these classes still work like normal classes, but by creating certain restrictions on them now, there's some hope that they can be converted into Value Types when Java 10 gets that feature.

Supposing it ends up happening, I see two main advantages to converting these types to value types:

  1. Improved performance, since you don't need to use heap space.
  2. Value types are never null, so if you have a field of type OptionalDouble and you never initialize it, you still won't get null pointer exceptions.

Shameless plug: I've leveraged these attributes of struct types in C# for the Maybe<> type in a library I wrote.

like image 34
StriplingWarrior Avatar answered Oct 29 '22 17:10

StriplingWarrior