黑马程序员技术交流社区

标题: java String类内存分配的一个问题 [打印本页]

作者: 姚远    时间: 2012-5-11 05:40
标题: java String类内存分配的一个问题
String str = "123";
请问 这个字符串"123"是存在栈区还是存在堆区?
作者: 李啸    时间: 2012-5-11 06:41
当然是堆区
作者: Gao23616    时间: 2012-5-11 06:48

堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。

栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。

堆里都是存储对象
栈中主要存放一些基本类型的变量(,int, short, long, byte, float, double, boolean, char)

作者: 刘_浩    时间: 2012-5-11 08:15
在堆中,而且是在堆的缓冲区中。
作者: 杨鹏    时间: 2012-5-11 08:43
字符串是常量,创建之后它们的值是不可以改变的,所以它们可以共享。字符串如果没有new对象,那么这个字符串是存在堆区中的一块区域叫缓冲区(常量池)。正如楼主提供的代码String str = "123";该语句在执行的时候,虚拟机会的常量池中是否存在"123"这个常量,如果不存在则在常量池中创建,下次再有String str1 = "123",那么str1不会再创建这个对象,直接指向常量池中已经存在的"123"。但是如果是String str = new String("123"),那会在堆内存创建一个"123"对象,并且也会在常量池中查看是否有该对象,如果有则不创建,如果没有则也会在常量池创建一个"123"。
作者: 金肖    时间: 2012-5-11 08:56
String内存图解

String内存图解.png (25.91 KB, 下载次数: 64)

String内存图解.png

作者: 张成龙    时间: 2012-5-11 08:57
在堆中的缓冲区,但String str = "123";是否创建新对象取决于堆中的缓冲区是否已经存在了"123",
如果已经存在,则不创建对象,只是将引用指向已经存在的"123",否则就会new出一个新的对象"123"。
作者: 田林    时间: 2012-5-11 09:30
String str = "123";中的“123”存在于方法区中的常量池(constant pool)中的字符串(String pool)中。
String类对象初始化总结:
1.String s = “aaa”; (采用字面值方式赋值)

1) 查找String Pool  中是否存在“aaa ”这个对象,如果不存在,则在String Pool  中创建  一个“aaa ”对象,然后将String  Pool  中的这个“aaa ”对象的地址返回来,赋给引用变量s,这样s 会指向String Pool  中的这个“aaa ”字符串对象

2) 如果存在,则不创建任何对象,直接将String Pool 中的这个“aaa ”对象地址返回来, 赋给s 引用。

2. String s = new String(“aaa”);

1) 首先在String Pool  中查找有没有“aaa ”这个字符串对象,如果有,则不在String Pool  中再去创建“aaa ”这个对象了,直接在堆中(heap )中创建一个“aaa ”字符串对

   象,然后将堆中的这个“aaa ”对象的地址返回来,赋给s 引用,导致s 指向了堆中创建的这个“aaa ”字符串对象。

2) 如果没有,则首先在String Pool  中创建一个“aaa  “对象,然后再在堆中(heap)创建一个”aaa  “对象,然后将堆中的这个”aaa  “对象的地址返回来,赋给s  引用,

   导致s 指向了堆中所创建的这个”aaa  “对象。


作者: 黄坚声    时间: 2012-5-11 09:46
"123"是对象,对象时存在Java 的堆空间里的。
变量才是在Java栈区
作者: 孙峰    时间: 2012-5-11 10:16
String对象的创建   关键是要明白其原理。

原理1:当使用任何方式来创建一个字符串对象s时,Java运行时(运行中JVM)会拿着这个X在String池中找是否存在内容相同的字符串对象,如果不存在,则在池中创建一个字符串s,否则,不在池中添加。
  
原理2:Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。
  
原理3:使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象。
  
原理4:使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2