This article is participating in “Java Theme Month – Java Debug Notes Event”, see < Event link > for more details.

It’s a good idea to know where your data is stored when your program is running. Of particular concern is the allocation of memory. There are six places to store data:

(1) register

This is the fastest save area because it’s in a different place than all the others: inside the processor. However, the number of registers is very limited, so registers are allocated by the compiler as needed. We have no direct control over this, and it is impossible to find any trace of registers in our own programs.

(2) Stack

The object itself is not stored on the stack, but in the heap (new objects) or in the constant pool (string constant objects are stored in the constant pool). Resides in a regular RAM (random access memory) area, but can be directly supported for processing through its “stack pointer.” Moving the stack pointer down creates new memory; If you move it up, it frees that memory. This is an exceptionally fast and efficient way to store data, second only to registers. When creating a program, the Java compiler must know exactly the “length” and “age” of all the data held in the stack. This is because it must generate code to move the pointer up and down. This limitation definitely affects the program’s flexibility, so while some Java data is stored on the stack — specifically, object handles — Java objects are not.

(3) The heap

Holds all new objects, a general-purpose memory pool (also in the RAM area) that holds Java objects. Unlike a stack, the most attractive aspect of a “memory Heap” or “Heap” is that the compiler does not have to know how much storage space to allocate from the Heap or how long the stored data will stay in the Heap. As a result, you get more flexibility when you store data in the heap. When you ask to create an object, you simply code it with the new command. As the code executes, the data is automatically saved in the heap. Of course, this flexibility comes at a price: it takes longer to allocate storage in the heap!

(4) Static storage

** stores static members (defined as static), where “static” means “in a fixed location” (although also in RAM). Statically stored data is always waiting to be invoked while the program is running. The static keyword can be used to indicate that a particular element of an object is static. But Java objects themselves are never put into static storage.

(5) Constant storage

Store string constants and primitives (public static final). Constant values are usually placed directly inside program code. It is safe to do so because they will never change. Some constants require strict protection, so consider putting them in read-only memory (ROM).

(6) Non-RAM storage

If data is completely independent of a program, it can exist when the program is not running and is outside the control of the program. Two of the most important examples are “streaming objects” and “fixed objects.” For streaming objects, the object becomes a byte stream, which is usually sent to another machine. For fixed objects, objects are stored on disk. Even when programs are aborted, they retain their state. A particularly useful trick for these types of data stores is that they can exist in other media. They can even be restored to normal, RAM-based objects if needed. Java 1.1 provides support for Lightweight Persistence. Future versions may even provide a more complete solution

Here we are mainly concerned with stacks, heaps, and constant pools. Objects in stacks and constant pools can be shared, but objects in the heap cannot be shared. The size and lifetime of the data in the stack are determinable, and when no reference points to the data, it disappears. The garbage collector is responsible for collecting objects in the heap, so the size and life cycle need not be determined, giving you great flexibility. For strings: references to objects are stored on the stack, in the constant pool if they are created at compile time (defined directly in double quotes), and in the heap if they are determined at run time (new). For strings equal to equals, there is always only one copy in the constant pool and multiple copies in the heap. Such as the following code:

 String s1 = "china";   
 String s2 = "china";   
 String s3 = "china";   
 String ss1 = new String("china");   
 String ss2 = new String("china");   
 String ss3 = new String("china");  
Copy the code

To explain the three yellow arrows, when a string is generated from new (say “China”), the constant pool will first look to see if there is already a “China” object. If there is not, the constant pool will create a string object in the constant pool, and then create a copy of the constant pool object in the heap. String s = new String(” xyz “); How many objects are generated? One or two, if there is no “XYZ” in the constant pool.

For variables and constants of the base type: variables and references are stored on the stack, and constants are stored in the constant pool. Such as the following code:

int i1 = 9;   
int i2 = 9;   
int i3 = 9;    
public static final int INT1 = 9;   
public static final int INT2 = 9;   
public static final int INT3 = 9;  
Copy the code

For member variables and local variables: a member variable is a variable defined outside a method but inside a class. Local variables are variables defined inside a method or statement block. Local variables must be initialized. Formal parameters are local variables whose data is stored in stack memory. Local variables in stack memory disappear as the method disappears. Member variables are stored in objects in the heap and are collected by the garbage collector. Such as the following code:

class BirthDate { private int day; private int month; private int year; public BirthDate(int d, int m, int y) { day = d; month = m; year = y; } omit get,set methods...... } public class Test{ public static void main(String args[]){ int date = 9; Test test = new Test(); test.change(date); The BirthDate d1 = new BirthDate,7,1970 (7); } public void change1(int i){ i = 1234; }}Copy the code

For this code, date is the local variable, I,d,m,y are the local variables, day, month, year are the member variables. 1. Main: int date = 9; Date local variables, base types, references, and values all reside on the stack. 2. Test test = new Test(); The object (new test ()) is stored in the heap. 3. test.change(date); I is a local variable, and references and values are stored on the stack. When the change method completes, I is removed from the stack. BirthDate d1= new BirthDate(7,7,1970); D1 is the object reference and is stored in the stack, and the object (new BirthDate()) is stored in the heap, where D, M, and Y are local variables stored in the stack and their types are base types, so their data is also stored in the stack. Day,month, and Year are member variables stored in the heap (new BirthDate()). When the BirthDate constructor completes, d, M, and y disappear from the stack. 5. After the main method is executed, the date variables, test, and d1 references disappear from the stack, and new test () and new BirthDate() await garbage collection.