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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 小黑子 中级黑马   /  2014-7-31 21:24  /  1557 人查看  /  11 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 小黑子 于 2014-8-5 21:53 编辑

照着毕老师的讲的画的,但是觉得他的些地方讲得的点模糊,不知道自己画的对不对,尤其是那几个步骤,求大神指导~~

8_单例设计模式的内存问题.png (134.68 KB, 下载次数: 15)

8_单例设计模式的内存问题.png

评分

参与人数 1技术分 +1 收起 理由
格子、 + 1 赞一个!

查看全部评分

11 个回复

倒序浏览
没人啊,大神大神你在哪里???
回复 使用道具 举报
求大神指导呀

点评

现在水贴少多了,表自己刷楼了啊  发表于 2014-8-7 11:35
回复 使用道具 举报
是不是太乱了,没人看得懂:dizzy:
回复 使用道具 举报
看不清楚 !
回复 使用道具 举报
本帖最后由 怀念黑海岸 于 2014-8-3 17:42 编辑

恩,看了下你的图,你采用的恶寒式单例,别的先不说,你这个加载过程就不对,静态变量是归属于类空间的,所以当你编译好这个类时其实你的这个单例对象他就已经创建好了,存在于静态变量区。所以new Student()这步并不是在运行时才执行的。它已经先于你主函数的调用运行而存在了。除非你吧这个程序给kill掉,否则只要这个程序还要运行,你这个程序中产生的这个对象将一直存在于内存中,你对这个类的对象的所有操作其实都是操作你定义的那个静态的变量s。
回复 使用道具 举报
怀念黑海岸 发表于 2014-8-3 17:39
恩,看了下你的图,你采用的恶寒式单例,别的先不说,你这个加载过程就不对,静态变量是归属于类空间的,所 ...

哦,谢谢哈。那是不是应该这样:
1、编译时,类Student中的静态变量s与静态方法getInstance( )加载进方法区中的静态区
     main函数加载进栈(是整个main加载进栈,还是main的某些东西加载进栈???比如说,在栈中建立了个s)
2、运行时,Student.getInstance( )将类Student中剩下的属性与方法(即非静态的)加载进方法区的非静态区。
3、getInstance()需建立new Student( ),故在堆中开辟空间,并将地址赋给方法区的s
4、new Student( )需使用构造函数,故使用已经加载进方法区非静态区的构造函数
——————————————————————————————————————————
是不是这个样子啊,唉,我自己都觉得有点乱………………
回复 使用道具 举报
其实单例模式很好理解,就是类只调用了一次构造方法,构建对象实例。而引用就像遥控器,对象实例就像电视机,一个电视机可以配很多遥控器,去操作电视机
回复 使用道具 举报
小黑子 发表于 2014-8-4 09:12
哦,谢谢哈。那是不是应该这样:
1、编译时,类Student中的静态变量s与静态方法getInstance( )加载进方法 ...

你main中的代码要运行,也得通过编译后才能被jvm识别啊,所以mian函数是随着程序一起被加载进方法区,指数main函数中的代码在程序开始运行时,产生的各种临时变量会存在于栈中,你定义这个引用变量s其实还是指向的是事先就声明好的静态变量s,你代码是归属于类的,他们随着类文件.class的加载而被加载进入方法区中,你运行这个程序的时候其实他所有代码都被加载进入了方法区了,new 关键字是在堆空间真正的创建一个对象,getInstance方法只是将事先创建好的这个Student对象的地址传递给你新创建的这个位于栈的临时变量s,你这个临时变量s是指向的只是静态变量s,至于这个静态变量s究竟存在于哪个区间我也不清楚,查了很多资料都没看个明白,我会继续查,查到了再来完善我的回答。
回复 使用道具 举报
本帖最后由 怀念黑海岸 于 2014-8-4 11:56 编辑
小黑子 发表于 2014-8-4 09:12
哦,谢谢哈。那是不是应该这样:
1、编译时,类Student中的静态变量s与静态方法getInstance( )加载进方法 ...

我查到相关资料了,现在来补充下:
       第一个问题:main方法作为执行代码他是会随着类的class文件加载到内存中方法区中的代码区中的,而你main方法定义的各种变量则是存在于为main方法开辟的栈中的,你在main方法中建立一个对象引用s,这个s也是存在于main方法的栈中的。
      第二个问题:Student中定义的非静态的变量他们是属于对象空间的,而他们则是定义在调用当前这个对象的线程私有的栈区间内,你在这个对象中定义的各种变量,和这个对象涉及到所操作的方法中定义的局部变量等等,都是存放在这个线程私有空间内
      第三个问题:你声明的那个静态变量student s,当类文件加载到内存时它被初始化(即加载类文件时就完成new Student()步骤)。记好:java中凡是通过new关键字产生的对象。不管是静态的还是非静态的,共有的还是私有的,都是存在于堆空间中的。你getInstance方法是将这个静态变量的地址赋值给了主函数中定义的s,
     第四个问题:因为单例中的构造函数是被私有的,我们在程序开始运行时是无法创建这个类的对象的,除非在这个类的内部使用(但是频繁的创建对象就是去了单例模式的特点了)。而且构造函数是不能用static修饰的。
     

评分

参与人数 1技术分 +2 收起 理由
格子、 + 2 很给力!很用心!欢迎继续和大家一起交流!.

查看全部评分

回复 使用道具 举报
怀念黑海岸 发表于 2014-8-4 11:54
我查到相关资料了,现在来补充下:
       第一个问题:main方法作为执行代码他是会随着类的class文件加载 ...

非常感谢,我还得多看几遍,多琢磨琢磨,谢谢。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马