Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Are all objects in Java assigned to the heap?

2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly explains "whether the objects in Java are all allocated on the heap". Interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn whether all the objects in Java are assigned to the heap.

Preface

In the process of learning to use Java, it is generally believed that the objects out of new are allocated on the heap, but this conclusion is not so absolute. Through the analysis of the process of Java object allocation, we can know that there are two places that lead to objects that come out of new in Java are not necessarily on the heap. These two points are the escape analysis in Java and TLAB (Thread Local Allocation Buffer). This paper first introduces the two, and then introduces the process of Java object allocation.

1. Escape analysis

1.1 definition of escape analysis

Escape analysis is a cross-function global data flow analysis algorithm which can effectively reduce the synchronous load and memory heap allocation pressure in Java programs. Through escape analysis, the Java Hotspot compiler can analyze the scope of use of a reference to a new object and decide whether to assign the object to the heap.

In the principle of computer language compiler optimization, escape analysis refers to the method of analyzing pointer dynamic range, which is related to pointer analysis and shape analysis of compiler optimization principle. When a variable (or object) is allocated in a method, its pointer may be returned or referenced globally, thus being referenced by other procedures or threads, a phenomenon called Escape of pointers (or references).

Java supports and turns on the escape analysis option by default in Java SE 6u23 and later versions. Java's HotSpot JIT compiler can analyze the escape of code when the method is overloaded or dynamically loaded. At the same time, the characteristics of Java object allocation on the heap and built-in threads make escape analysis an important function of Java.

1.2 methods of escape analysis

The Java Hotspot compiler uses the

[plain] view plain copy Choi J D, Gupta M, Serrano M, et al. Escape analysis for Java [J]. Acm Sigplan Notices, 1999, 34 (10): 1-19.

Jong-Deok Choi, Manish Gupta, Mauricio Seffano,Vugranam C. Sreedhar, Sam Midkiff and other algorithms described in the paper "Escape Analysis for Java" for escape analysis. In this algorithm, connected graph is introduced, and the reachability relationship between object and object reference is constructed by connected graph. On the basis of this, a combined data flow analysis method is proposed. Because the algorithm is context-sensitive and flow-sensitive, and simulates the nesting relationship of any level of objects, the analysis accuracy is high, but the running time and memory consumption are relatively large.

Most of the implementation of escape analysis is based on the premise of a so-called "closed world" (closed world): all methods that may be executed are known before the escape analysis is done, and the actual operation of the program does not change the calling relationship between them. But this assumption is not true when a real Java program is running. Many of the features of Java programs, such as dynamic class loading, calling local functions, and reflecting program calls, will break the so-called "closed world" convention.

Whether in the "closed world" or "open world", escape analysis, as an algorithm rather than a programming language, has attracted a large number of scholars at home and abroad to study it.

1.3 treatment after escape analysis

After escape analysis, the escape states of three kinds of objects can be obtained.

GlobalEscape (global escape), that is, a reference to an object escapes from a method or thread. For example, a reference to an object is copied to a class variable, or stored in an object that has escaped, or a reference to that object is returned to the calling method as the return value of the method.

ArgEscape (parameter level escape), that is, passing the application of an object to a method during a method call. This state can be determined by analyzing the binaries of the called method.

NoEscape (no escape), an object that can be replaced by a scalar. Such objects can not be assigned to the traditional heap.

The compiler can optimize the program using the results of escape analysis.

Heap allocation objects become stack allocation objects. If the object in a method, the reference to the object does not escape, the method may be allocated on the stack memory rather than on the usual heap memory.

Eliminate synchronization. The cost of thread synchronization is quite high, and the consequence of synchronization is to reduce concurrency and performance. Escape analysis can determine whether an object is always accessed by only one thread, and if accessed by only one thread, the synchronization operation on the object can be transformed into an operation without synchronization protection, which can greatly improve the degree of concurrency and performance.

Vector substitution. Escape analysis method can save part or even all of the object in the CPU register if it is found that the memory structure of the object does not need to be carried out continuously, which can greatly improve the access speed.

Next, let's look at an example of escape analysis.

Class Main {public static void main (String [] args) {example ();} public static void example () {Foo foo = new Foo (); / / alloc Bar bar = new Bar (); / / alloc bar.setFoo (foo);} class Foo {} class Bar {private Foo foo; public void setFoo (Foo foo) {this.foo = foo;}}

In this example, we create two objects, the Foo object and the Bar object, and we assign the application of the Foo object to the method of the Bar object. At this point, if the Bar pair is on the heap, it will cause the Foo object to escape, but in this case, through escape analysis, the compiler can know that the Bar object did not escape the example () method, so this also means that Foo did not escape the example method either. Therefore, the compiler can assign these two objects to the stack.

1.4 effect of compiler after escape analysis

Test the code:

Package com.yang.test2; / * Created by yangzl2008 on 2015-1-29. * / class EscapeAnalysis {private static class Foo {private int x; private static int counter; public Foo () {x = (+ + counter);}} public static void main (String [] args) {long start = System.nanoTime (); for (int I = 0; I

< 1000 * 1000 * 10; ++i) { Foo foo = new Foo(); } long end = System.nanoTime(); System.out.println("Time cost is " + (end - start)); } } 设置JVM运行参数: 未开启逃逸分析设置为: -server -verbose:gc 开启逃逸分析设置为: -server -verbose:gc -XX:+DoEscapeAnalysis 在未开启逃逸分析的状况下运行情况如下: [GC 5376K->

427K (63872K), 0.0006051 secs] [GC 5803K-> 43872K (63872K), 0.0003928 secs] [GC 5803K-> 43872K (63872K), 0.0003639 secs] [GC 5803K-> 427K (69248K), 0.0003770 secs] [GC 11179K-> 427K (69248K), 0.0003987 secs] [GC 11179K-> 427K (79552K), 0.0003817 secs] [GC 21931K-> 399K (79552K), 0.0004342 secs] [GC 21903K-> 399K (101120K), 0.0002175 secs] [GC 43343K-> 399K (101184K) 0.0001421 secs] Time cost is 58514571

When escape analysis is enabled, the operation is as follows:

Time cost is 10031306

When the escape analysis is not enabled, the appeal code is run, and JVM performs the GC operation, while when the escape analysis is enabled, JVM does not perform the GC operation. At the same time, in terms of operating time, the running time of the program that opens the escape analysis is 1 / 5 of the time of the unopened escape analysis.

2. TLAB

JVM opens up a small thread private area in the new generation of Eden Space in memory, called TLAB (Thread-local allocation buffer). The default setting is 1% of Eden Space. In Java programs, many objects are small and discarded after use, and they are suitable for fast GC without thread sharing, so JVM usually gives priority to TLAB for small objects, and the allocation on TLAB has no lock overhead because of thread privacy. Therefore, in practice, the efficiency of allocating multiple small objects is usually higher than that of allocating a large object.

In other words, each thread in Java has its own buffer called TLAB (Thread-local allocation buffer), and each TLAB has only one thread to operate. TLAB combined with bump-the-pointer technology can achieve fast object allocation without any lock synchronization, that is to say, when objects are allocated, they do not need to lock the whole heap, but only need to allocate them in their own buffer.

For the JDK source code for object allocation, please see the analysis of OpenJDK source code in JVM's Java object creation [initialization].

3. The process of Java object allocation

Through escape analysis, the compiler determines whether objects are allocated on the stack or on the heap. If it is allocated on the heap, enter option 2.

If tlab_top + size

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report