Heap and stack in Java

This article is reprinted from https://www.cnblogs.com/iblieve618/p/6380328.html

First, let’s talk about the most basic points

Basic data types and local variables are stored in the stack memory and disappear when they are used up.
The instantiated objects and arrays created by new are stored in the heap memory, and are automatically eliminated from time to time by the garbage collection mechanism after they are used up.

 

 

Second, first clarify the above two points, the following example is better to understand


Example 1

main()
  int x=1;
show ()
  int x=2

The variable int x=1 is defined in the main function main(), and the variable int x=1 is defined in the show() function. Finally, the show() function is executed.


Steps to perform the above procedure:

Step 1 - The main() function is the program entry. The JVM executes it first, and opens up a space in the stack memory to store the int type variable x and attach the value 1 at the same time.
Step 2 - JVM executes the show() function, and opens up a new space in the stack memory to store the int type variable x and attach the value 2 at the same time.
     At this time, the main space and the show space coexist and run at the same time without affecting each other.
Step 3 - After show() is executed, the variable x is released immediately and the space disappears. But the main() function space still exists, and the variable x in main still exists and is not affected.

The schematic diagram is as follows:

 

——————————————————————————————————————————————————————————————————————

Example 2

main()
  int[] x=new int[3];
  x[0]=20

The main function main() defines an array x, the element type is int, and the number of elements is 3.

以上程序执行步骤
第1步——执行int[] x=new int[3];
  隐藏以下几分支
  JVM执行main()函数,在栈内存中开辟一个空间,存放x变量(x变量是局部变量)。
  同时,在堆内存中也开辟一个空间,存放new int[3]数组,堆内存会自动内存首地址值,如0x0045。
  数组在栈内存中的地址值,会附给x,这样x也有地址值。所以,x就指向(引用)了这个数组。此时,所有元素均未附值,但都有默认初始化值0。

第2步——执行x[0]=20
  即在堆内存中将20附给[0]这个数组元素。这样,数组的三个元素值分别为20,0,0

示图如下:

——————————————————————————————————————————————————————————————————————


示例3
main()
  int[] x=new int[3];
  x[0]=20
  x=null;

以上步骤执行步骤
第1、2步——与示例2完全一样,略。

第3步——执行x=null;
  null表示空值,即x的引用数组内存地址0x0045被删除了,则不再指向栈内存中的数组。此时,堆中的数组不再被x使用了,即被视为垃圾,JVM会启动垃圾回收机制,不定时自动删除。

示图如下

——————————————————————————————————————————————————————————————————

示例4
main()
  int[] x=new int[3];
  int[] y=x;
  y[1]=100
  x=null;

以上步骤执行步骤

第1步——与示例2第1步一致,略。
第2步——执行int[] y=x,
  在栈内存定义了新的数组变量内存y,同时将x的值0x0045附给了y。所以,y也指向了堆内存中的同一个数组。
第3步——执行y[1]=100
  即在堆内存中将20附给[0]这个数组元素。这样,数组的三个元素值分别为0,100,0
第4步——执行x=null
  则变量x不再指向栈内存中的数组了。但是,变量y仍然指向,所以数组不消失。

示图如下

——————————————————————————————————————————————————————————————————

示例5

Car c=new Car;
c.color="blue";
Car c1=new Car;
c1.num=5;

 虽然是个对象都引用new Car,但是是两个不同的对象。每一次new,都产生不同的实体

 

——————————————————————————————————————————————————————————————————

示例6

Car c=new Car;
c.num=5;
Car c1=c;
c1.color="green";
c.run();

Car c1=c,这句话相当于将对象复制一份出来,两个对象的内存地址值一样。所以指向同一个实体,对c1的属性修改,相当于c的属性也改了。

 

 

三、栈和堆的特点

栈:

函数中定义的基本类型变量,对象的引用变量都在函数的栈内存中分配。
栈内存特点,数数据一执行完毕,变量会立即释放,节约内存空间。
栈内存中的数据,没有默认初始化值,需要手动设置。

 

堆:

堆内存用来存放new创建的对象和数组。
堆内存中所有的实体都有内存地址值。
堆内存中的实体是用来封装数据的,这些数据都有默认初始化值。
堆内存中的实体不再被指向时,JVM启动垃圾回收机制,自动清除,这也是JAVA优于C++的表现之一(C++中需要程序员手动清除)。

 

注:

什么是局部变量:定义在函数中的变量、定义在函数中的参数上的变量、定义在for循环内部的变量


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324598151&siteId=291194637