A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 大牛1 中级黑马   /  2016-5-26 21:27  /  2232 人查看  /  27 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制.
2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中。)
3. 堆:存放所有new出来的对象。
4.  静态域 :存放静态成员(static定义的)
5.  常量池 :存放字符串常量和基本类型常量(public static final)。
6. 非RAM存储:硬盘等永久存储空间
这里我们主要关心栈,堆和常量池,对于 栈和常量池中的对象可以共享,对于堆中的对象不可以共享。栈中的数据大小和生命周期是可以确定的,当没有引用指向数据时,这个数据就会消失。堆中的对象的由垃圾回收器负责回收,因此大小和生命周期不需要确定 ,具有很大的灵活性。
对于字符串:其对象的引用都是存储在栈中的,如果是 编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中 。对于equals相等的字符串,在常量池中永远只有一份,在堆中有多份。
new String("China");
对于通过new产生一个字符串(假设为”china”)时,会先去常量池中查找是否已经有了”china”对象,如果没有则在常量池中创建一个此字符串对象,然后堆中再创建一个常量池中此”china”对象的拷贝对象。这也就是有道面试题:String s = new String(“xyz”);产生几个对象?一个或两个,如果常量池中原来没有”xyz”,就是两个。
对于成员变量和局部变量:成员变量就是方法外部,类的内部定义的变量;局部变量就是方法或语句块内部定义的变量。局部变量必须初始化。
形式参数是局部变量,局部变量的数据存在于栈内存中 。栈内存中的局部变量随着方法的消失而消失。
成员变量存储在堆中的对象里面 ,由垃圾回收器负责回收

27 个回复

正序浏览
不错呢……
回复 使用道具 举报

共同学习
回复 使用道具 举报
说的很详细,清晰
回复 使用道具 举报
学习了学习了
回复 使用道具 举报
给力,很好!
回复 使用道具 举报

共同努力吧
回复 使用道具 举报
谢谢楼主,学习了
回复 使用道具 举报
chenshaohua 发表于 2016-5-29 10:13
总结的很详细啊!!!

哈哈,共同努力
回复 使用道具 举报
总结的很详细啊!!!
回复 使用道具 举报
guolongfei344 发表于 2016-5-28 22:14
还不错,已经收藏!

好东西当然要和大家一起分享啦
回复 使用道具 举报
还不错,已经收藏!
回复 使用道具 举报
Kingchen 发表于 2016-5-27 22:48
学习学习,顶一个!

哈哈,共同进步
回复 使用道具 举报
ygxheima 发表于 2016-5-27 22:55
原来是这样, 终于明白了方法区的存储了,楼主威武,谢了!!!

哈哈,不客气
回复 使用道具 举报
大牛1 发表于 2016-5-27 22:45
举个简单的例子:

首先你得明白,栈区,堆区,方法区

原来是这样, 终于明白了方法区的存储了,楼主威武,谢了!!!
回复 使用道具 举报
学习学习,顶一个!
回复 使用道具 举报
ygxheima 发表于 2016-5-27 17:01
那那个堆中的对象不能共享怎么理解?是说即使是两个相同属性的也会在堆中开辟两个空间么? ...

举个简单的例子:
  1. /*
  2. 举个简单的例子,先看代码
  3. 定义一个类:
  4. Student
  5. 成员变量:
  6. name
  7. age
  8. 成员方法:
  9. eat()
  10. sleep()
  11. 然后定义一个测试类:
  12. StudentDemo
  13. 在测试类中声明两个Student对象:
  14. Student1
  15. Student2
  16. 然后分别创建这两个对象
  17. */

  18. //定义Student类
  19. class Student{

  20.     private String name;
  21.     private int age;
  22.     Student{

  23.       }

  24.     public void eat(){
  25.           System.out.println("肚子饿了,去吃饭");

  26.      public void sleep(){
  27.           System.out.println("学习累了,睡觉休息");
  28.       }

  29. }

  30. //测试类StudentDemo

  31. class StudentDemo{

  32. public static void main(String[] args){

  33.        Student s1 = new Student();
  34.        Student s2 = new Student();

  35. }

  36. }
复制代码

首先你得明白,栈区,堆区,方法区
方法区:存放的是类的 .class 文件,是方法的存储地址
下面分析s1,s2这两个对象的创建过程:
准确的说 s1 和 s2 是两个对象引用。
代码从 main 方法处开始执行
在栈中开辟出一块区域
然后 s1 加载进栈
new 在堆区开辟出一块区域
在堆区创建 name , age 等成员变量,并初始化。并且 将方法的引用地址也存放在堆中。最后把堆区的成员变量的首地址加载进栈区。
然后 s1 加载进栈
new 在堆区开辟出一块区域
在堆区创建 name , age 等成员变量,并初始化。并且 将方法的引用地址也存放在堆中。最后把堆区的成员变量的首地址加载进栈区。
从上面的描述你看到了吧,在堆中,s1所指向的对象,和s2 所指向的对象,在不同的堆区。所以说成员变量不能共享,但是方法是共享的。
所以,你明白了吧,在堆区重新创建成员变量并初始化,并把方法的引用地址放进堆中;
当再创建一个 new 的时候,在堆区再重新创建成员变量并初始化,并把方法的引用地址放进堆中;
注意,这里方法的引用地址是相同的
好了,希望可以帮到你


回复 使用道具 举报 1 0
大牛1 发表于 2016-5-26 21:46
不好意思。我还没学到线程呢,这个只是我目前的理解程度

那那个堆中的对象不能共享怎么理解?是说即使是两个相同属性的也会在堆中开辟两个空间么?
回复 使用道具 举报
顶一个了。
回复 使用道具 举报
大笑哈哈 发表于 2016-5-26 22:16
牛逼,朋友说论坛是水黑马币的地方,现在看来他就是一本正经的胡说八道

哈哈。不同的人有不同的见解吧。既然选择搞技术,总要用心一点吧。
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马