Learn the stack memory heap memory

Because java garbage collection mechanism, so tend not to pay attention to the stack heap memory allocation until OOM

First, understand the concept of a stack heap

1, create an instance of the storage heap [objects]

  1. The program starts running, JVM get some memory from OS, is part of heap memory. Heap memory typically underlying the storage addresses arranged upward.
  2. Stack is a "run-time" data field, the class is instantiated objects allocated from the heap up space;
  3. Space is allocated on the heap by "new" and other instructions establishment, the heap is dynamically allocated memory size, survival do not have to tell the compiler in advance;
  4. Unlike C ++ is, Java automatically manage the stack and heap, the garbage collector can automatically reclaim unused memory heap;
  5. The disadvantage is that, due to the dynamic allocation of memory at run-time, so the memory access slower.

2, stack [storage] basic types and reference types

  1. Last-out data structure, usually in a method for storing parameters, local variables;
  2. In java, all basic types (short, int, long, byte, float, double, boolean, char), and reference type of variables are stored in the stack;
  3. Living space in the stack data in the current generally Scopes ({...} by the enclosed region;
  4. Stack access speed faster than the reactor, located directly behind the CPU registers;
  5. Data can be shared stack, a plurality of reference can point to the same address;
  6. The downside is that the data on the stack size and survival must be determined, lack of flexibility.

3, summary

  1. Java heap memory allocated to the operating system is part of the JVM memory.
  2. When we create objects that are stored in the Java heap memory.
  3. You can adjust the size of the Java heap space by using JVM command-line options -Xms, -Xmx, -Xmn.
  4. The basic types of data stored in the stack: short, int, long, byte, float, double, boolean, char
  5. Just create new objects in the form of, then stored in a java heap memory.

Second, the data stored in the stack

1, the basic types of data storage

int a = 3;
int b = 3;

编译器先处理int a = 3;
首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,
然后将a指向3的地址。接着处理int b = 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。
这样,就出现了a与b同时均指向3的情况。

所以 a == b true

2、包装类数据存储

如Integer, Double, String等将相应的基本数据类型包装起来的类。
这些类数据全部存在于堆中,Java用new()语句来显示地告诉编译器,在运行时才根据需要动态创建,因此比较灵活,但缺点是要占用更多的时间。

以String为例

String是一个特殊的包装类数据。即可以用String str = new String("abc");的形式来创建,也可以用String str = "abc";的形式来创建。
前者是规范的类的创建过程,即在Java中,一切都是对象,而对象是类的实例,全部通过new()的形式来创建。

那为什么在String str = "abc";中,并没有通过new()来创建实例,是不是违反了上述原则?其实没有。

关于String str = "abc"的内部工作。Java内部将此语句转化为以下几个步骤:

  • a、先定义一个名为str的对String类的对象引用变量:String str;
  • b、在栈中查找有没有存放值为"abc"的地址,如果没有,则开辟一个存放字面值为"abc"的地址,接着创建一个新的String类的对象O,并将O的字符串值指向这个地址,而且在栈中这个地址旁边记下这个引用的对象O。如果已经有了值为"abc"的地址,则查找对象O,并返回O的地址。
  • c、将str指向对象O的地址。
     值得注意的是,通常String类中字符串值都是直接存值的。但像String str = "abc";这种场合下,其字符串值却是保存了一个指向存在栈中数据的引用(即:String str = "abc";既有栈存储,又有堆存储)。

为了更好地说明这个问题,我们可以通过以下的几个代码进行验证。

String str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2); //true

只有在两个引用都指向了同一个对象时才返回真值。str1与str2是否都指向了同一个对象)

结果说明,JVM创建了两个引用str1和str2,但只创建了一个对象,而且两个引用都指向了这个对象。

3、总结

(1). 我们在使用诸如String str = "abc";的格式定义类时,总是想当然地认为,我们创建了String类的对象str。

担心陷阱!对象可能并没有被创建!唯一可以肯定的是,指向 String类的引用被创建了。
至于这个引用到底是否指向了一个新的对象,必须根据上下文来考虑,除非你通过new()方法来显要地创建一个新的对象。
因此,更为准确的说法是,我们创建了一个指向String类的对象的引用变量str,这个对象引用变量指向了某个值为"abc"的String类。
清醒地认识到这一点对排除程序中难以发现的bug是很有帮助的。

(2). 使用String str = "abc";的方式,可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。
而对于String str = new String("abc");的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。

(3). 由于String类的immutable性质(因为包装类的值不可修改),当String变量需要经常变换其值时,应该考虑使用StringBuffer类,以提高程序效率。

4、实例

String s = new String("abc") 创建了几个对象?

首先我们要明白两个概念,引用变量和对象,对象一般通过new在堆中创建,s只是一个引用变量。

答案2个。

5、知识点

我们可以用==判断一下两个引用变量是否指向了一个地址即一个对象

Guess you like

Origin www.cnblogs.com/niceyoo/p/11084391.html