A Shanghai Morgan Stanley interviewer asked in a 2017 java interview.
One hypothesis — no free() or delete() in java, so the memory manager doesn’t need to handle reclaiming and reusing the memory. [[optimizedC++]] P333 confirmed the c++ mem mgr need that. Instead the GC uses a very different algorithm — see below.
One hypothesis — after a warm-up period, based on heuristics JIT compiler could aggressively compile bytecode into machine code with speedy shortcuts for the “normal” code path + special code path to handle the abnormal conditions. Here’s an analogy — if every borrower seen so far has acceptable credit score, the bank may simplify credit check and have special procedure to deal with defaults. For most of the cases this work flow is faster than the traditional. P76 [[java performance]] gave an example. A java method calls obj1.equals(obj2). Based on heuristics, JIT knows that all previous calls have obj1 being a String object, so JIT can generate assembly code to
- call String.equals() and go ahead to read some field of the String object obj1
- if no such field, then obj1 is not String, then backtrack and use obj1 vtable to look up the virtual method obj1.equals()
It may turn out that 99.9% of the time we can skip the time-consuming Step 2.
http://www.javaworld.com/article/2076593/performance-tests-show-java-as-fast-as-c–.html is a 1998 research.
In my GS-PWM days, a colleague circulated a publication that java could match C in performance, but they didn’t say “surpass”
https://stackoverflow.com/questions/1984856/java-runtime-performance-vs-native-c-c-code is not a published expert but he says:
On average, a garbage collector is far faster than manual memory management, for many reasons:
- on a managed heap, dynamic allocations can be done much faster than the classic heap
- shared ownership can be handled with negligible amortized cost, where in a native language you’d have to use reference counting which is awfully expensive
- in some (possibly rare and contrived) cases, object destruction is vastly simplified as well (Most Java objects can be reclaimed just by GC’ing the memory block. In C++ destructors must always be executed)