'Builder design pattern performance Java 8 vs Java 17

I wrote simple class named Person based on Builder Design Pattern like this:

public class Person {
    private long id;
    private String name;

    private Person(PersonBuilder builder) {
        this.id = builder.id;
        this.name = builder.name;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public static class PersonBuilder {
        private long id;
        private String name;

        public PersonBuilder setId(long id) {
            this.id = id;
            return this;
        }

        public PersonBuilder setName(String name) {
            this.name = name;
            return this;
        }

        public Person build() {
            return new Person(this);
        }
    }
}

I compare performance of this class on Java 8 and Java 17. In Java 8, two objects are created to reach person.

enter image description here

However, in Java 17 only one object:

enter image description here

I want to understand:

  1. How objects managed in JVM 17?
  2. what happened to PersonBuilder object in JVM 17?

Note: I use Java VisualVM for monitoring JVM

Please check this code if you have any doubts about my question.
This code only creates Person object in Java 17.

public class MainClass {
    public static void main(String[] args) {
        while (true) {
            Person person = new Person.PersonBuilder()
                    .setId(1)
                    .setName("ali")
                    .build();
        }
    }
}

enter image description here



Solution 1:[1]

My suspicion is that you are just seeing an "artifact". For some reason, the VisualVM profiler doesn't see the PersonBuilder instance. A plausible explanation is that it is no longer reachable and has been garbage collected ... by the time that VisualVM has created the heap snapshot to examine.

It is theoretically possible that the JIT compiler could perform use escape analysis to determine that the PersonBuilder object doesn't escape the method call and then optimize away its creation. However:

  1. This use-case is probably too complicated for that.
  2. It is unlikely that this code has been JIT compiled anyway. (Unless you are running the main method a few thousand times in a loop ...)

UPDATE

In your updated code, it is plausible that the code has been JIT compiled. Therefore, this might be a result of escape analysis + JIT optimization.

If that is the case then the overall explanation is simply that the Java 17 JIT compiler is optimizing differently to Java 8.


I would also suggest that you are wasting your time trying to measure object creation at this granularity. Frankly, a difference of 24 bytes in an JVM process whose memory size is a number of megabytes is irrelevant. If you do it a few million times, maybe it will be significant, except that then you have the issue that this is not a realistic benchmark. (You wouldn't create and immediately discard bazzillions of objects like that in a real application.)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1