Detailed explanation of java stack

Java divides memory into two types: one is stack memory and the other is heap memory.   
  Some basic type variables and object reference variables defined in the function are allocated in the function's stack memory.  
  When a variable is defined in a code block, Java allocates memory space for the variable in the stack. When the scope of the variable is exceeded, Java will automatically release the memory space allocated for the variable, and the memory space can be used immediately. for other purposes.  
  Heap memory is used to store objects and arrays created by new.  
Memory allocated in the heap is managed by the Java Virtual Machine's automatic garbage collector.  
  After an array or object is generated 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, and the variable in the stack becomes Array or object reference variable.  
A reference variable is equivalent to a name for an array or object, and you can use the reference variable in the stack to access the array or object in the heap later in the program. 
/**************************************************** ****************************/ 

The stack and heap are both places that Java uses to store data in Ram. Unlike C++, Java automatically manages the stack and heap, and the programmer cannot set the stack or heap directly. 

Java's heap is a runtime data area from which class (objects) allocate space. These objects are created by instructions such as new, newarray, anewarray, and multianewarray, and they do not need to be explicitly freed by program code. The heap is responsible for garbage collection. Yes, the advantage of the heap is that the memory size can be dynamically allocated, and the lifetime does not have to be told to the compiler in advance, because it allocates memory dynamically at runtime, and Java's garbage collector will automatically collect these data that are no longer used. But The disadvantage is that the access speed is slower due to the dynamic allocation of memory at runtime. 

The advantage of the stack is that the access speed is faster than the heap, second only to the register, and the stack data can be shared. But the disadvantage is that the size and lifetime of the data stored in the stack must be deterministic, which lacks 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 particularity, that is, the data stored in the stack can be shared. Suppose we define at the same time: 
int a = 3; 
int b = 3; 
the compiler first processes int a = 3; first it creates a reference to the variable a on the stack, and then checks to see if there is a value of 3 on the stack, if not If found, store 3 in, and then point a to 3. Then process int b = 3; after creating the reference variable of b, because there is already a value of 3 in the stack, it will point b directly to 3. In this way, a and b both point to 3 at the same time. 

At this time, if a=4 is set again; then the compiler will re-search whether there is a value of 4 in the stack, if not, it will store 4 and make a point to 4; if it already exists, directly point a to this address . Therefore, changes in the value of a will not affect the value of b. 

It should be noted that this sharing of data is different from this sharing of two object references pointing to one object at the same time, because in this case the modification of a does not affect b, it is done by the compiler, it is beneficial save space. An object reference variable modifies the internal state of the object, which affects another object reference variable. 

String is a special wrapper class data. You can use: 
String str = new String("abc"); 
String str = "abc"; 
There are two forms to create, the first is to use new() to create a new object, which will be stored in the heap. A new object is created each time it is called. 
而第二种是先在栈中创建一个对String类的对象引用变量str,然后查找栈中有没有存放"abc",如果没有,则将"abc"存放进栈,并令str指向”abc”,如果已经有”abc” 则直接令str指向“abc”。 

比较类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用==,下面用例子说明上面的理论。 
String str1 = "abc"; 
String str2 = "abc"; 
System.out.println(str1==str2); //true 
可以看出str1和str2是指向同一个对象的。 

String str1 =new String ("abc"); 
String str2 =new String ("abc"); 
System.out.println(str1==str2); // false 
用new的方式是生成不同的对象。每一次生成一个。 


因此用第一种方式创建多个”abc”字符串,在内存中其实只存在一个对象而已. 这种写法有利与节省内存空间. 同时它可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str = new String("abc");的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。 

另一方面, 要注意: 我们在使用诸如String str = "abc";的格式定义类时,总是想当然地认为,创建了String类的对象str。担心陷阱!对象可能并没有被创建!而可能只是指向一个先前已经创建的对象。只有通过new()方法才能保证每次都创建一个新的对象。 
由于String类的immutable性质,当String变量需要经常变换其值时,应该考虑使用StringBuffer类,以提高程序效率。 

/**********************************************************************************/ 

在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。  
   
  当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作 

他用。  
   
  堆内存用来存放由new创建的对象和数组。  
   
  在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。  
   
  在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变 

量。  
   
  引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。 

Guess you like

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