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

Asked

Viewed 168 times

8

Article link: http://www.vogella.com/tutorials/JavaPerformance/article.html#Escape%20Analysis

"The Programming language(Java) does not Offer the possibility to Let the Programmer decides if an Object should be generated in the stack. But in Certain cases it would be Desirable to allocate an Object on the stack, as 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 placed in the stack and the JVM takes care of it internally. My question is the following: what are the criteria that make an object eligible to be allocated in the stack and not in the heap? It is guaranteed that an object that has the requirements to be allocated in the stack is?

2 answers

6

First understand the reasons for not being able to allocate an object to stack. Take advantage and try to understand the functioning of stack and of heap, if you still have doubts.

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

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

  • The main and easy to discover is that the object needs to be small. It can be said that the JVM always knows the size of the object when going to instantiate. I just can’t guarantee that it’s always viable to verify this, I believe it is, but if for some reason there’s a case that isn’t, size indetermination will prevent optimization. In general any normal class has sufficient size, arrays even if used in composition to a class is that they may have difficulty.
  • The text speaks clearly that it is made a exhaust analysis to make sure that the object does not leave the domains of the method in any way: by direct return, by attaching to any other object that can be returned, referenced by the argument passed to the method, including there the hidden parameter this giving access to the members of the panel.

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

In some cases even not escaping may not compensate put in stack because it may impair the reference location of the objects making the composition.

  • It is possible that there are other specific criteria that I would not know. Any minimum impediment will avoid optimization. The JVM will certainly prefer a false negative that hinders a possible optimization than a false positive that creates a failure or instability to the JVM.

It is not guaranteed that the object goes to the stack

Like all optimization, do not count on it, it will only occur 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 another, either by a change of JVM, or by a change in your code. Not always a change makes clear what may occur.

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

  • 1

    remember that there are several implementations of JVM, and these criteria may vary between them.

  • @Viniciuszaramella yes, I improved the answer

5


What are the criteria that make an object eligible to be allocated in the stack and not in the heap?

  1. Fit into the allocated space.
    Note that you can set the size of stack with the parameter -Xss. If you are working on a critical project can make a "crazy" how to pass -Xss512m or -Xss1g for the command java.
    However, like every other thread maid has a stack own, you usually have to balance the available memory with the amount of threads of its application.
  2. Object must be "local".
    According to the documentation there may be 3 analysis results:
    • GlobalEscape: Method and method "leak" object thread. For example: it is stored in a static attribute, stored in an attribute of another object that also "leaks" or returned from the method.
    • ArgEscape: object is passed as argument or referenced by an argument in the call to another method. JVM analyzes bytecode to determine if this occurs.
    • NoEscape - A "local" or "scale" object, meaning that the allocation can be removed from the generated code.

After analysis, there are several optimizations that can enter the scene, such as removing sync blocks can be eliminated if the JVM detects that the object does not leak to others threads.

However, only in the latter case, if you have a "local" object, the allocation can occur in the stack.

It is guaranteed that an object that has the requirements to be allocated in the stack is?

Not.

First, you should always check the set of Features of the JVM you are using. What is often cited is that the technique Escaping Analysis 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).

According to, always check if there are flags to enable or disable such Features. In this case, it seems you can do it with -XX:+DoEscapeAnalysis or -XX:-DoEscapeAnalysis. Also check if other flags can impact this, such as -Xss that I mentioned above.

Third, always do the test. Create a mini-benchmark to determine if the optimization is actually occurring by comparing an execution with Feature on and off.

Considerations

Remember that Java leaves memory management hidden* in a black box for project purposes. It is not that it does not explicitly allow you to allocate an object in stack and yes that it should not allow. Of course this can be a disadvantage if you are a expert performance, but it also means that Java can apply this optimization to the other 99.9% who don’t even know it.

* Actually java allows some things that make direct access to memory (ByteBuffer's, for example). This is used, for example, in critical I/O operations as in drivers of databases (and, of course, always end up causing leakage and memory overflow problems).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.