gzyueqian
18078865874
首页 > 新闻中心 > > 正文

JAVA中的堆与栈

更新时间: 2007-05-10 13:44:13来源: 粤嵌教育浏览量:930


  1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方,本文对其进行比较。

  2. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享,详见第3点。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。

  3. Java中的数据类型有两种。基本类型(primitive types), 共有8种,即int, short, long, byte, float, double, boolean, char。存在于栈中。另一种是包装类数据,如Integer, String, Double等将相应的基本数据类型包装起来的类。这些类数据全部存在于堆中.

String str = "abc"; 和String str = new String("abc"); 和char[] c = {'a','b','c'}; String str=new String(c); 都采用堆存储

String str = "abc"; 在栈中如果没有存放值为"abc"的地址,等同于:
String temp=new String("abc");
String str=temp;

关于String str = "abc"的内部工作。Java内部将此语句转化为以下几个步骤:
  (1)先定义一个名为str的对String类的对象引用变量:String str;

  (2)在栈中查找有没有存放值为"abc"的地址,如果没有,则开辟一个存放字面值为"abc"的地址,接着创建一个新的String类的对象o,并将o的字符串值指向这个地址,而且在栈中这个地址旁边记下这个引用的对象o。如果已经有了值为"abc"的地址,则查找对象o,并返回o的地址。

  (3)将str指向对象o的地址。

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

char[] c = {'a','b','c'}; String str=new String(c); 等同于:
String str = new String('a'+'b'+'c');
====================================================================================

1.
class Test
{
public static void main(String[] args)
{
String s = "123";
}
}


Runtime Heap Summary: Test
==========================

Runtime Instance List
---------------------

Package Class Count Cumulative Count Memory Cumulative Memory
------- ----- ----- ---------------- ------ -----------------
Total 2 (100.0%) 2 (100.0%) 48 (100.0%) 48 (100.0%)
java.lang String 1 (50.0%) 1 (50.0%) 24 (50.0%) 24 (50.0%)
char[ ] 1 (50.0%) 1 (50.0%) 24 (50.0%) 24 (50.0%)

Report Date: 2007-4-26 15:27:49
结论:String s = "123",会创建一个"123"字符数组和一个String对象。

2.
class Test
{
public static void main(String[] args)
{
String s = new String("123");
}
}


Runtime Heap Summary: Test
==========================

Runtime Instance List
---------------------

Package Class Count Cumulative Count Memory Cumulative Memory
------- ----- ----- ---------------- ------ -----------------
Total 3 (100.0%) 3 (100.0%) 72 (100.0%) 72 (100.0%)
java.lang String 2 (66.7%) 2 (66.7%) 48 (66.7%) 48 (66.7%)
char[ ] 1 (33.3%) 1 (33.3%) 24 (33.3%) 24 (33.3%)

Report Date: 2007-4-26 15:29:07

  结论:String s = new String("123"); 根据上面的测试可以看出,"123"创建了一个数组,一个String对象,而new String()又根据"123"对象作为参数,重新生成了一个新的String对象,此对象被s变量引用。

3.
class Test
{
public static void main(String[] args)
{
String s1 = "123";
String s2 = "123";
if (s1 == s2) {
System.out.println("s1==s2");
} else {
System.out.println("s1!=s2");
}
}
}
输出结果:s1==s2

4.
class Test
{
public static void main(String[] args)
{
String s1 = new String("123");
String s2 = new String("123");
if (s1 == s2) {
System.out.println("s1==s2");
} else {
System.out.println("s1!=s2");
}
}
}
结果:s1!=s2

5.
class Test
{
public static void main(String[] args)
{
String s1 = new String("123");
String s2 = new String("123");
}
}

Runtime Heap Summary: Test
==========================

Runtime Instance List
---------------------

Package Class Count Cumulative Count Memory Cumulative Memory
------- ----- ----- ---------------- ------ -----------------
Total 4 (100.0%) 4 (100.0%) 96 (100.0%) 96 (100.0%)
java.lang String 3 (75.0%) 3 (75.0%) 72 (75.0%) 72 (75.0%)
char[ ] 1 (25.0%) 1 (25.0%) 24 (25.0%) 24 (25.0%)

Report Date: 2007-4-26 15:41:50
  结论:相同字符串常量,即使在不同语句中被引用,其内存是共用的,"123"只生成一个字符数据和一个

String对象,两个new String()分别生成了一个对象。

6.
class Test
{
public static void main(String[] args)
{
String s1 = new String("123");
String s2 = new String("1234");
}
}

Runtime Heap Summary: Test
==========================

Runtime Instance List
---------------------

Package Class Count Cumulative Count Memory Cumulative Memory
------- ----- ----- ---------------- ------ -----------------
Total 6 (100.0%) 6 (100.0%) 144 (100.0%) 144 (100.0%)
java.lang String 4 (66.7%) 4 (66.7%) 96 (66.7%) 96 (66.7%)
char[ ] 2 (33.3%) 2 (33.3%) 48 (33.3%) 48 (33.3%)

Report Date: 2007-4-26 15:43:45
  结论:"123"和"1234"分别生成了各自的字符数组和String对象。两个new String()分别创建一个String对象。

免费预约试听课