Java堆栈

精简至: http://blog.csdn.net/clam_clam/article/details/6829960

程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的.

静态的:静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求

堆区:

1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令) 
2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身

栈区:

1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中 
2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。 
3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。

方法区:

1.又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。 
2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。


栈:一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配(,int, short, long, byte, float, double, boolean, char)
优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性
回收:当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。
堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。

堆:堆内存用于存放由new创建的对象和数组(通过new、newarray、anewarray和multianewarray等指令建立)
回收:数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因


常量池:存放字符串常量和基本类型常量(public static final)。有时,在嵌入式系统中,常量本身会和其他部分分割离开(由于版权等其他原因),所以在这种情况下,可以选择将其放在ROM中 。

栈中的变量指向堆内存中的变量,这就是 Java 中的指针!

JVM是基于堆栈的虚拟机.JVM为每个新创建的线程都分配一个堆栈.


问题的引入:

问题一:

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

问题二:

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

问题三:

String s1 = "ja";
String s2 = "va";
String s3 = "java";
String s4 = s1 + s2;
System.out.println(s3 == s4);//false
System.out.println(s3.equals(s4));//true //重写才会编程true

String类对equals方法进行了重写,用来比较指向的字符串对象所存储的字符串是否相等
equals方法,注意:equals方法不能作用于基本数据类型的变量

如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;

问题4:

String s1 = "ja"; 
String s2 = s1; 
String s3 = s1; 

s1=null

System.out.println(s3 );// ja

创建了一个内容为 “ja” 的String对象,并将其引用赋值给s2,s2是一个String类型的引用

原文地址:https://www.cnblogs.com/season-xie/p/6337600.html