What are the criteria that make an object eligible to be allocated in the stack and not in the heap?
Fit in the allocated space.
Note that you can set the stack size with the -Xss
parameter. If you are working on a critical project it can be crazy to pass -Xss512m
or -Xss1g
to the java
command.
However, since each thread created has its own stack , you usually have to balance the available memory with the amount of threads of your application. / li>
Object must be "local" .
According to the documentation there may be 3 results of the analysis:
-
GlobalEscape
: Object "leaks" from method and thread . For example, it is stored in a static attribute, stored in an attribute of another object that also "leaks" or is returned from the method.
-
ArgEscape
: object is passed as an argument or referenced by an argument in the call to another method. The JVM parses the bytecode to determine if this occurs.
-
NoEscape
- A "local" or "scalar" object, meaning that the allocation can be removed from the generated code.
After the analysis, there are several optimizations that can go into the scene, such as removing synchronization blocks can be eliminated if the JVM detects that the object does not leak to other threads .
However, only in the latter case, if you have a "local" object, the allocation can occur in stack .
Is it guaranteed that an object that has the requirements to be allocated on the stack actually is?
No.
First , you should always check the set of features of the JVM you are using. What is often cited is that the Escaping Analysis technique was introduced in Java SE 6 Update 23, so you can assume that later versions have this technique ( until version 8 the documentation cites this ).
Second , always check for flags to enable or disable such features . In this case, it looks like you can do this with -XX:+DoEscapeAnalysis
or -XX:-DoEscapeAnalysis
. Also check if other flags can impact this, such as the% w_that I mentioned above.
Third , always take the test. Create a mini-benchmark to determine if optimization is actually occurring by comparing an execution with the on and off .
Considerations
Remember that Java leaves hidden memory management * in a black box for the sake of design. It's not that it does not explicitly allow you to allocate an object in the stack , but rather that it should not allow it. Of course this can be a disadvantage if you are an expert in performance, but this also means that Java can apply this optimization to the other 99.9% who do not even know of this possibility.
* Actually java allows some things that make direct memory access ( -Xss
's, for example). This is used, for example, in critical I / O operations as in database drivers (and, of course, always end up causing leak and memory overflow problems).