1. 寄存器 :寄存器根据需求分配。不能直接手动分配,故在程序中是感受不到寄存器的存在的。
  2. 堆栈 :位于通用RAM中,通过操作栈顶指针来进行分配以及释放内存。指针向下移动则分配内存,向上移动则释放内存。这种分配内存的方式,仅次于寄存器分配速度。但上下移动指针必须知道堆栈所有的项的生命周期,这限制了程序灵活性。一般存放一些局部变量和函数参数 等。堆栈一个重要的特性是存在栈中的数据可以共享。如下代码
int a=5;
int b=5;

         编译器先处理a=5;首先它会在栈中创建一个变量为a的内存空间,然后查找有没有字面值为5的地址,没找到,就开辟一个存放5这个字面值的地址,然后将a指向字面值为5的地址。接着处理b= 5;在创建完b的引用变量后,由于在栈中已经有5这个字面值,便将b直接指向5的地址。这样,就出现了a与b同时均指向5的情况。但学过C的童鞋可能就觉得这个和指针指向是不是一样的呢?如果改变了a的值,b的值是不是会随之而发生变化呢?但其实在Java中这是不存在的。\(-_-)/

         Java中这种通过字面值的引用来修改其值,不会导致另一个指向此字面值的引用的值也跟着改变的情况。如上例,我们定义完a与b的值后,再令a=4;那么,b不会等于4,还是等于5。在编译器内部,遇到a=4;时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。(PS:堆栈是栈,不是堆哦)

堆 :位于通用的内存池中,用于存放所有的Java对象。堆不用知道堆中的所有项的生命周期,这样可以更为灵活,但在进行new存储分配和GC时会比堆栈需要更多的时间。

  关于String这个特殊的包装类的small tip:
  a:String str = new String(“abc”);的形式来创建,也可以用String str = “abc”初始化;划重点~_~
       这两种的存储位置可是不一样的哦!前者是存储在堆里,后者可是存储在栈里的哦.前者是通过new在堆里分配了一块内存,然后把“abc”放到其中,后者则是拆分为了三个步骤进行:
       (1)先定义一个名为str的对String类的对象引用变量:String str;
       (2)在栈中查找有没有存放值为”abc”的地址,如果没有,则开辟一个存放字面值为”abc”的地址,接着创建一个新的String类的对象o,并将o的字符串值指向这个地址,而且在栈中这个地址旁边记下这个引用的对象o。如果已经有了值为”abc”的地址,则查找对象o,并返回o的地址。
       (3)将str指向对象o的地址。
  所以String str = “abc”也满足栈中的字面值引用。两个字符串指向同一个引用,其中一个字符串发生了改变,另一个字符串不会发生变化。

b:字符串str的值一经初识化就不可改变的,如果人为的改变了值,JVM会new一个String赋给str.所以如果在字符串需要频繁地变化值时,需使用stringBuilder.

c:判断两个对象是否指向同一个引用,equals()则是判断string的值是否相等。

4.程序代码 :常量值通常直接存储在程序代码内部。

5.非RAM存储 :对象存放在磁盘数据库里。
6.静态存储区 :存储static声明的静态变量。对象中的非static变量是在堆中的,但static类型的数据是属于该类所有对象共享的,所以不放在堆中,而是在静态存储区中.