Repost: Thinking and Summary of Java Memory

xiaoxiao2021-04-09  347

1. Java and stacks

6 places can be used to save data at the Java program:

(1) Register. The fastest storage area is located inside the processor, which is very limited, it is assigned by the compiler as needed. We have no direct control.

(2) Stack. Residing in a regular RAM (random access memory) area, this is a particularly fast, particularly effective data storage method, second only to the register. When you create a program, the Java compiler must accurately know "length" and "existing time" of all data saved in the stack. This lost a certain flexibility, so the object handle is stored in the stack, but the Java object does not place it.

(3) Heap (HEAP). The Java object is saved. Unlike the stack, it is the most attractive place that the compiler does not have to know how much storage space is to be allocated from the heap, and you don't have to know how long the stored data is to stay in the stack. Therefore, greater flexibility is obtained when saving data with a stack. When you create an object, just use the new command to prepare the relevant code. When you perform these code, you will automatically save the data in the stack. Of course, in order to achieve this flexibility, it will inevitably pay a certain price: it will take a longer time when allocating the storage space!

(4) Static storage. "Static" here refers to "located in a fixed position" (although in the RAM). During the operation, the static stored data will wait any time. The STATIC keyword can be used to indicate a particular element of an object is static. But the Java object itself will never place static storage.

(5) constant storage. The constant value is usually placed inside the program code. This is safe because they will never change. Some constants need to be strictly protected, so they can consider placing them into read-only memory (ROM).

(6) Non-RAM storage. The data is completely independent of a program, and the program can still be existing when the program is not running, and outside the program's control range.

2. The difference between the stack and stack

The stack is where Java is used to store data in RAM. Unlike C , Java automatic management stacks and stacks, programmers cannot set up stacks or stacks directly.

Java's heap is a runtime data area, class (objects allocated space. These objects are established throughout, NEWARRAY, ANEWARRAY and MULTIANEWARRAY, without program code to explicitly release. Piles are responsible for garbage collection The advantage of the heap is to dynamically allocate memory size, and the survival period does not have to tell the compiler in advance because it is dynamically allocated in the runtime, and the Java garbage collector will automatically receive these no longer used data. But The disadvantage is that the access speed is slower because of the dynamic distribution of memory during runtime.

The advantage of the stack is that the access speed is faster than the pile, second only to the register, and the stack data can be shared. However, the disadvantage is that the data size in the stack must be determined, lack of flexibility. The stack mainly stores some basic types of variables (, int, short, long, byte, float, double, boolean, char), and object handles.

The stack has a very important person, which is that the data in the stack can be shared. Suppose we define:

INT A = 3;

INT b = 3;

The compiler processes int a = 3; first it creates a reference to a variable in the stack, and then looks out if there is 3 value in the stack. If you are not found, you will store 3, and then point A to 3. Then process int b = 3; after the reference variable of the B is created, the B directs B directly to 3. Thus, the case where A and B are simultaneously pointed to 3.

At this time, if A = 4 is again; then the compiler will re-search for 4 values ​​in the stack. If not, store 4 stored in, and let A point to 4; if it is already, you point to this address . Therefore, the change in A value does not affect the value of B. It is important to pay attention to this sharing of this data and the reference to the two objects, which points to an object is different, because the modification of this case does not affect B, which is completed by the compiler, it is conducive to save space. And an object reference variable modifies the internal state of this object, affects another object reference variable.

String is a special packaging class data. Can use:

String str = new string ("ABC");

String str = "abc";

In both forms of forms, the first is to use new () to create new objects, which will be stored in the heap. A new object will be created each time you call.

The second is to create an object reference variable Str for the String class in the stack, and then the "ABC" is stored in the lookup stack. If not, "ABC" is stored in the stack, and the STR points to "ABC" If there is already "ABC", the STR is directly to "ABC".

When the value in the comparison class is equal, use the equals () method; if the reference to the two packaging classes is tested to point to the same object, use ==, the following example will be used to explain the theory of the above.

String str1 = "abc";

String str2 = "abc";

System.out.Println (str1 == str2); // true

It can be seen that STR1 and STR2 are the same object.

String str1 = new string ("ABC");

String str2 = new string ("abc");

System.out.println (str1 == str2); // false

The way to generate different objects in the way. Generate one every time.

Therefore, multiple "ABC" strings are created in the second way. There is only one object in memory. This way is advantageous to save memory space. At the same time it can improve the running speed of the program to a certain extent, because JVM will Automatically determine if there is a need to create a new object according to the actual situation of the data in the stack. For String Str = New String ("ABC"), the code is created in the heap, regardless of whether its string value is equal, it is necessary to create a new object, thus agggetting the burden of the program.

On the other hand, pay attention to: When we use the format definition class, we always think that the String class object STR is created. Worried about traps! Objects may not be created! It may just point to a previously created object. Only by the new () method can guarantee a new object every time.

Due to the IMMutable nature of the String class, when String variables need to change their values ​​frequently, consider using the StringBuffer class to improve program efficiency.

references:

Thoughts on Java Stack and Pile

http://www.duduwolf.com/post/3.asp

Chapter 2 Everything is an object

Http://52cg.com/training/kaifa/java/200510/31900.html

3. About the size of the data occupied in Java occupies

--test environment

J2ME MIDP1.0

--testing method:

With the following statement, get the memory values ​​before and after the object creation, and their differences are the memory size occupied by the created object: 1. i = runtime.getRuntime (). FreeMemory ();

2. Control = New Control (Control.Head_Move, 1, 1);

3. J = runtime.getRuntime (). freememory ();

4. System.out.println (i-j);

This method is not accurate, because JVM will run some things in the background, such as in GC, the background running something will occupy a certain amount, if the background program runs between 1,3 sentences, it will cause no accurate.

In order to keep the correctness as much as possible, the statement becomes the following, first GC, and then retest memory, let the memory that occupied by the background run out.

Runtime.getRuntime (). Gc ();

Thread.yield ();

i = runtime.getRuntime (). FreeMemory ();

Test T = New Test ();

Runtime.getRuntime (). Gc ();

Thread.yield ();

J = runtime.getRuntime (). freememory ();

System.out.println (i-j);

However, this method is still not necessarily guaranteed that the GC will be called, so the data obtained by each test is the same data, and the data displayed after the heap size is stable, and pursue as accurate as possible.

(1) i = runtime.getRuntime (). Freememory ();

INT T = 0;

CHAR A = 'a';

Long L = 23410389;

J = runtime.getRuntime (). freememory ();

System.out.println (i-j); // 0

[Conclusion] Because the basic data type is stored in the stack, it does not take up the memory of the heap. It can be seen that the value returned by FreeMemory is the memory in the heap, so the value is 0.

(2)

i = runtime.getRuntime (). FreeMemory ();

String S2 = "1234567";

J = runtime.getRuntime (). freememory ();

System.out.println (i-j); // 0

-------------------------------

i = runtime.getRuntime (). FreeMemory ();

String S2 = New String ("1234567");

J = runtime.getRuntime (). freememory ();

System.out.println (i-j); // 56

[Conclusion] The string created in String S2 = "1234567" is stored in the stack, it does not take up the stack; and use string s2 = new string ("1234567"); the string created in the manner is stored in the heap It takes up 56Byte's heap space.

(3)

Runtime.getRuntime (). Gc ();

Thread.yield ();

i = runtime.getRuntime (). FreeMemory ();

Test T = New Test (); // Test is an empty class

Runtime.getRuntime (). Gc (); thread.yield ();

J = runtime.getRuntime (). freememory ();

System.out.println (i-j); // 12

--------------------------------

Runtime.getRuntime (). Gc ();

Thread.yield ();

i = runtime.getRuntime (). FreeMemory ();

Contorl C = New Control (control.Head_move, 1, 1);

Runtime.getRuntime (). Gc ();

Thread.yield ();

J = runtime.getRuntime (). freememory ();

System.out.println (i-j); // 112

[Conclusion 1]: An empty object requires a 12Byte's heap space to understand it as a target head.

[Conclusion 2]: A "Head_Move" object in ZHANGUO / Control takes up 112byte heap space.

Why is it 112byte?

There are 25 non-Static basic data types and reference variables, while the basic data types such as int, short, byte and the memory size occupied by reference variables are 4Byte (see 4), so the size is:

25 * 4 12 (object head) == 112

(4) Add: private int a = 0 in the Class Test above;

Result: 16byte,

From (3), you can know the empty Object 12Byte, so an int occupably 4Byte's space.

Change IN to other basic data types, test with the same method, and draw the following conclusions:

[Conclusion 1]: float, boolean, byte, short, int, char occupies 4 Byte's space,

Long, Double occupies 8Byte space (Midp1.0 does not support float and double)

Quote variables, such as Control C = NULL, occupying 4Byte space.

[Conclusion 2]: Decisive behavior in Java, not size; use Byte to limit the role of data, but can not save memory, in memory, Byte and Int are occupied 4byte space.

[Conclusion 3]: Although A is a basic data type, it is an attribute of the object T dynamically created at runtime, so it is also stored in a heap, occupying a stack of 4byte.

(5) Add the following statement in the Class Test: and remove the variable INT A added to (4).

PRIVATE FINAL INT J = 1;

PRIVATE FINAL Static Int K = 4;

Private static void testfunction () {

}

Result: 12

[Conclusion 1] The amount of Object's occupancy is only related to the basic data type of non-Static in the class and the reference variables, and the number of static variables and Function is not related. Static is stored in "Static Storage Space" and does not take up a stack of space.

[Conclusion 2] For classes that need to generate multiple objects, such as Control, etc., the member variables in the class are try to use Static because the non-STAITC variables in the object need to occupy a certain space in the heap. When the number of Object is more, occupied The stack of space will increase. It is prone to prone to insufficient memory (mainly a stack of spaces) to cause "application error". (6)

i = runtime.getRuntime (). FreeMemory ();

Strin s = new string ("");

J = runtime.getRuntime (). freememory ();

System.out.println (i-j); // 40

[Conclusion] An empty string is to take up 40-byte heap space, understand the String header information, avoiding the same String in the code, but should be used in the above (2) the way:

String S2 = "1234567" to generate string.

(7)

Runtime.getRuntime (). Gc ();

Thread.yield ();

i = runtime.getRuntime (). FreeMemory ();

INT a [] [] = new int [0] [0];

Runtime.getRuntime (). Gc ();

Thread.yield ();

J = runtime.getRuntime (). freememory ();

System.out.println (i-j); // 16

-------------------------------------------------- --------------------------------

INT A [] [] = new int [1] [0]; // 36

Int a [] [] = new int [2] [0]; // 56

INT A [] [] = new int [3] [0]; // 76

Int a [] [] = new int [] [0]; // 4016

INT A [] [] = new int [200] [1]; // 4816, because more than 200 int is more than the above 800

[Conclusion 1] Each nested int [DIM2] is an object, an int occupably 4Byte space, and each object has a 16-byte array object head.

[Conclusion 2] The memory consumption of the two-dimensional array headers is very large, for mobile phones that are less memory, such as the NOKIA Old 40 Series, it is best to change the two-dimensional number of groups into one-dimensional array.

Reference article:

Discover How much memory an Object Consumes

http://www.mywelt.net/?q=node/577

Do you know the size of the data? - Don't spend too much effort to hide the members

Http://istudy.com.ru/article/software/java/20051025/54,81897,0.html

Todo:

1. With regard to the relationship between classes, variables, functions, etc., considering the role of the obfuscator, and it is not necessary to change in the program.

2. About the relationship between J2ME programs and memory is further deepened, such as thread, gc, etc.

? ? ?

转载请注明原文地址:https://www.9cbs.com/read-132986.html

New Post(0)