What makes an object eligible to be allocated on the stack?

7

Link to the article: link

  "The programming language (Java) does not offer the possibility to let the programmer decide if an object should be generated in the stack.   But in certain cases it would be desirable to allocate an object on   the stack, the memory allocation on the stack is cheaper than the   memory allocation in the heap ... "

According to this article, in Java, an object can be allocated in the stack and the JVM takes care of it internally. My question is: what are the criteria that make an object eligible to be allocated in the stack and not in the heap? Is it guaranteed that an object that has the requirements to be allocated in the stack is indeed?

    
asked by anonymous 04.04.2016 / 23:27

2 answers

4
  

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).

        
    05.04.2016 / 04:55
    5

    First understand the reasons why you can not allocate an object in stack . Enjoy and try to understand stack and heap >, if you still have questions.

    So the normal Java thing is to just put the primitive types in the stack (they can be in the heap too), since it meets the criteria of not escaping the scope method, be guaranteed very small, etc. (see the criteria in the link above). It is anticipated in future versions that the programmer will be able to create his own types with value semantics, as are the primitives, just as already occurs in C # .

    What the JVM can do with classes that are always allocated in heap is to optimize the allocation and put it on the stack when it can determine that this is possible. The main reasons for this are subject to verification of the actual implementation of the JVM, but we can infer some things that are the general criteria that govern memory allocation in any technology.

    • The main and easy to figure out is that the object needs to be small. It can be said that the JVM always knows the size of the object when it will instantiate. I just can not guarantee that it is always feasible to verify this, I believe so, but if for some reason there is a case that is not, indetermination of size will prevent optimization. In general, any normal class has enough size, even if it is used in composition to a class, it may have difficulty.
    • The text speaks clearly that an escape analysis is done to make sure that the object does not exit the method domains in any way: by direct return, by appending to any other object that can be returned, referenced by the argument passed to the method, including the hidden parameter this that gives access to instance members.

      If you can not prove that the object does not escape, it is preferable to keep in heap . Even if the object is small enough to make a copy, the expected external semantics do not allow the reference to be changed by the copied value.

    • There may be other specific criteria that I could not tell. Any minimal impediment will prevent optimization. The JVM will certainly prefer a false negative that hinders a possible optimization than a false positive that creates a flaw or instability to the JVM.

    It is not guaranteed that the object will go to the stack

    Like any optimization, do not count on it. It will happen to help. If you depend on it for something you are expecting more than you should. What can work one way at a time may no longer occur in another, either by a change in the JVM or by a change in your code. Not always a change makes clear what can happen.

    Optimization depends on implementation. It is not part of the specification that it should occur. So it depends on the JVM vendor, the version you're using, and the settings you've applied.

        
    04.04.2016 / 23:46