Java divides memory into two types: one is stack memory and the other is heap memory. Some basic types of variables and objects defined in the function are all in the stack memory of the function Allocation, When a variable is defined in a block of code, Java allocates memory space for the variable on the stack. When it exceeds the scope of the variable (for example, calling function B in function A , define variable a in function B. The scope of variable a is only function B. After function B runs, variable a will be automatically destroyed. The memory allocated to it will be recycled), and Java will automatically Release the memory space allocated for the variable, and the memory space can be used for other purposes immediately. Heap memory is used to store memory created by
newArray, memory allocated in the heap, automatically garbage by the Java virtual machine Recycler to manage. After generating an array or object in the heap, you can also define a special variable in the stack, so that the value of the variable in the stack is equal to the first address of the array or object in the heap memory. The variable in the stack It becomes a reference variable of the array or object. In the future, you can use the variables in the stack to access the array or object in the heap in the program. The reference variable is equivalent to giving a name to the array or object. Reference variables are ordinary variables that are allocated on the stack when defined. The reference variables are released after the program runs outside other scopes. Arrays and objects are allocated in the heap. Even if the program runs outside the code block where the array or object statement generated by new is located, the memory occupied by the array and object will not be released. Arrays and objects only become garbage when there are no reference variables pointing to them and can no longer be used. They will be collected (released) by the garbage collector at an unspecified time later. This is also the reason why Java takes up more memory. In fact, variables in the stack point to variables in the heap memory. This is a pointer in Java. Code example Demo1: Single object creation
class Person { String name ; int age ; public void tell() { System.out.println("姓名:"+name+",年龄:"+age); } } public class Demo1 { public static void main(String[] args) { Person per = new Person() ; } }In the above program, an object per is instantiated, and it needs to be stored in the memory during the instantiation process. Open up space, which includes stack memory and heap memory. The specific memory allocation is as shown in the figure below: Process We can find from the above figure that the object name per is saved in the stack memory (
A more accurate statement is that the object name per is saved in the stack memory. The access address of the memory space ), and the specific content of the object, such as the attributes name and age, are stored in the heap memory. Because the per object has only been instantiated and has not been assigned a specific value, it has default values.
The default value of stringis null, and the default value of type int is 0. As mentioned earlier, the heap memory space must be opened using the new keyword.
Code example Demo2: Multiple object creationclass Person { String name ; int age ; public void tell() { System.out.println("姓名:"+name+",年龄:"+age); } } public class Demo2 { public static void main(String[] args) { Person per1 = new Person() ; Person per2 = new Person() ; per1.name="张三" ; per1.age=30 ; per2.age=33 ; per1.tell(); per2.tell(); } }
Figure 1-2 Instantiate two objects
Key concept: Classes, like arrays, are reference types. Reference types mean that the same heap memory can be used by multiple objects. A stack memory points to, let's take a look at a simple example of reference passing.
Code example Demo3: Object reference transfer 1class Person {
String name ;
int age ;
public void tell() {
System.out.println("姓名:"+name+",年龄:"+age);
}
}
public class Demo3 {
public static void main(String[] args) {
Person per1 = new Person() ;
Person per2 = per1 ;//-------注意--------
per1.name="张三" ;
per1.age=30 ;
per2.age=33 ;
per1.tell();
per2.tell();
}
}
The program running result is:
From the running results of the program, we can find that
the output content of the two objects is the same. In fact, the so-called reference transfer is to transfer the usage rights of one heap memory space to multiple stack memory spaces. Each stack memory space can Modify the contents of the heap memory space. The memory allocation diagram of this program is as follows:
图1-3 对象引用的传递内存分配
图1-3 对象引用的传递内存分配(续)
注意:上述实例中对象per2没有堆内存空间,这是因为对象per2只进行声明操作,也没有进行实例化操作。只是使用new关键字,实例化以后才会有堆内存空间
代码实例Demo4:对象引用传递2
class Person { String name ; int age ; public void tell() { System.out.println("姓名:"+name+",年龄:"+age); } } public class Demo4 { public static void main(String[] args) { Person per1 = new Person() ; Person per2 = new Person() ; per1.name="张三" ; per1.age=30 ; per2.name="李四" ; per2.age=33 ; per2=per1 ;//-----注意---- per1.tell(); per2.tell(); } }
上述运行程序结果为:
从程序的输出结果可以发现跟Demo3差不多。不过内存分配发生了一些变化,具体如下所示:
图1-4 (垃圾对象)的产生
注意点:
1.Java本身提供垃圾收集机制(Garbage Collection,GC),会不定期释放不用的内存空间,只要对象不用了,就会等待GC释放空间,如上面堆内存中的name="李四";age=33。
2.一个栈内存只能指向一个堆内存空间,如果要想指向其他堆内存空间,则必须先断开已有的指向,才能分配新的指向。
Java中常见的内存区域
在Java中主要存在4块内存空间,这些内存的名称及作用如下:
1.栈内存空间:保存所有对象的名称。
2.堆内存空间:保存每个对象的具体属性内容。
3.全局数据区:保存static类型的属性值。
4.全局代码区:保存所有的方法定义。
The above is the detailed content of Detailed graphic explanation of Java's memory mechanism (with code). For more information, please follow other related articles on the PHP Chinese website!