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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© xieshuhua 中级黑马   /  2012-5-14 22:58  /  3265 人查看  /  18 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

大家帮忙看下,我总结的CPU运行过程正确吗?箭头是cpu的读取顺序。
我理解栈就是一个运动的过程,1,2,3,4,5有顺序,存在即会执行。所以栈有先进后出的特性,而且动作结束,系统就会自动回收了。
我的问题是:类实例化的时候,对象获得堆数据地址的同时,ss是否也获取了栈的数据地址?
ss运行结束后,还会保留其数据地址吗(下面的程序是否会引用未知)?
我理解堆是一个存放各种地址的集合,能new的都会存在堆中。存放数组所有成员的地址(数组成员的地址指向常量池或者其他变量地址),存放类成员的地址(变量,动作等)
CPU访问堆的时候,没有顺序,通过指针的偏移访问特定的变量(xx.yy就是将指针偏移到xx的yy方法并读取yy方法的地址)。所以栈就有灵活性的特点。Java通过gc进行回收,回收动作慢。
我的问题是:是不是栈直接一次运行里面的数值就会被销毁,堆里的内容需要反复判断再决定是否将内容销毁(这个有点高级啊)。
写了很多肯定有不对的,大家帮我指点下啊,谢谢啦。

xxx.png (46.07 KB, 下载次数: 45)

xxx.png

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1 赞一个!

查看全部评分

18 个回复

倒序浏览
大家有没有这种资料啊,介绍下~~
回复 使用道具 举报
可能写的太多了,大家多多见谅,我真的很想和大家讨论这方面问题。感兴趣的 我们在这里面相互讨论,共同提高。
回复 使用道具 举报
下图是我找的一个资料上面的介绍,可是我们一般认为3是存在常量池中的啊,大家怎么理解?

3333.png (15.9 KB, 下载次数: 46)

3333.png
回复 使用道具 举报
数据是先进入jvm的栈的,如果有new出现(即对象)的时候,就会有一个堆的地址赋给栈中,当堆中没有栈所调用的数据的时候,栈就会把内存释放。而堆中,如果不再有栈中的数据调用,就会被视为垃圾,但是不会被立即销毁,要等到jvm空闲的时候,利用java的回收机制,回收

评分

参与人数 2技术分 +1 黑马币 +5 收起 理由
贠(yun)靖 + 1
xieshuhua + 5 很认同

查看全部评分

回复 使用道具 举报
1,static静态方法,应该存放在静态方法区中,这样才可以直接类名调用。ss方法只有在被调用时才会进栈,不会在创建对象或者类加载就直接进栈。
2,ss运行结束之后,毫无因为会弹栈。
3,栈内运行的数据一旦执行完毕,就会立即弹栈,释放内存;而堆中的数据一旦没有被指向时,就会立即变成垃圾,等待垃圾回收机制的回收。

评分

参与人数 2技术分 +1 黑马币 +5 收起 理由
贠(yun)靖 + 1
xieshuhua + 5 赞一个!

查看全部评分

回复 使用道具 举报
hongbo 发表于 2012-5-14 23:42
数据是先进入jvm的栈的,如果有new出现(即对象)的时候,就会有一个堆的地址赋给栈中,当堆中没有栈所调用 ...

堆中没有栈所调用的数据?
这种情况出现,编译不能通过吧。没有需要的数据怎么运行哪?
回复 使用道具 举报
秦晓阳 发表于 2012-5-15 01:12
1,static静态方法,应该存放在静态方法区中,这样才可以直接类名调用。ss方法只有在被调用时才会进栈,不 ...

嗯,你说的很全面。
总结下,ss在类初始化的时候存放在静态方法区中,使用就会压入到栈中,使用结束就弹栈。
如果是非静态ss有是怎么样的哪?新建个对象后,ss会数据初始化吗?
另外我写的CPU运行过程正确吗?
回复 使用道具 举报
孙峰 黑马帝 2012-5-15 09:28:46
9#
你那个数组赋值语句不对吧,应该是{}的。

评分

参与人数 1黑马币 +1 收起 理由
xieshuhua + 1 没分了。。

查看全部评分

回复 使用道具 举报
孙峰 发表于 2012-5-15 09:28
你那个数组赋值语句不对吧,应该是{}的。

嗯嗯,我写错了,呵呵
回复 使用道具 举报
其实你那执行过程是有问题的。因为你给ss方法设置的static的 也就是静态的  凡是加static的成员属性和方法 都会存储在方法区的静态方块里面
堆内存中一般是存放  new出来的对象的    栈内存是存放变量和引用变量的  
回复 使用道具 举报
贠(yun)靖 发表于 2012-5-15 12:26
其实你那执行过程是有问题的。因为你给ss方法设置的static的 也就是静态的  凡是加static的成员属性和方法  ...

把ss设置为非静态,其他地方还有没有错误啊,就怕自己把错误的东西当成正确的。因为这些知识是我从网上总结的,不是从书上摘抄的。准确性没法保证。
回复 使用道具 举报
谢述华 发表于 2012-5-15 08:42
嗯,你说的很全面。
总结下,ss在类初始化的时候存放在静态方法区中,使用就会压入到栈中,使用结束就弹 ...

非静态ss方法是随着类的加载而存在的,在方法区中。创建对象时会在对象中存在一个ss方法,如果这个方法是对象特有的就可以定义方法体,覆盖原ss方法,和方法区中的ss方法无关。
回复 使用道具 举报
秦晓阳 发表于 2012-5-16 11:37
非静态ss方法是随着类的加载而存在的,在方法区中。创建对象时会在对象中存在一个ss方法,如果这个方法是 ...

嗯,你说的是静态和非静态加载的区别,CPU中运行的顺序又是怎么样的啊,我写了这么多,没有人肯定也没有人否定,好迷茫。。。
回复 使用道具 举报
楼主的理解完全错误。就楼主的代码上一个图吧。
回复 使用道具 举报
楼主的理解是错误的,就楼主的代码上个图吧。

评分

参与人数 2技术分 +1 黑马币 +5 收起 理由
职业规划-刘倩老师 + 1 赞一个!
xieshuhua + 5 很详细,我都没有接触到方法栈、方法区、计.

查看全部评分

回复 使用道具 举报
表示还没看到这,飘过。。。
回复 使用道具 举报
永恒之翼网络 发表于 2012-5-17 00:06
楼主的理解是错误的,就楼主的代码上个图吧。

太感谢了,画的真的很详细。不过我还是有不懂的地方,你能不能提供下这些知识的来源啊(出自那本书之类的),我自己去补充这方面知识。万分感激!
回复 使用道具 举报
常说的JVM的内存了。它主要分为五个部分——
1、Heap (堆):一个Java虚拟实例中只存在一个堆空间
2、Method Area(方法区域):被装载的class的信息存储在Method area的内存中。当虚拟机装载某个类型时,它使用类装载器定位相应的class文件,然后读入这个class文件内容并把它传输到虚拟机中。
3、Java Stack(java的栈):虚拟机只会直接对Java stack执行两种操作:以帧为单位的压栈或出栈
4、Program Counter(程序计数器):每一个线程都有它自己的PC寄存器,也是该线程启动时创建的。PC寄存器的内容总是指向下一条将被执行指令的饿地址,这里的地址可以是一个本地指针,也可以是在方法区中相对应于该方法起始指令的偏移量。  
5、Native method stack(本地方法栈):保存native方法进入区域的地址
以上五部分只有Heap 和Method Area是被所有线程的共享使用的;而Java stack, Program counter 和Native method stack是以线程为粒度的,每个线程独自拥有自己的部分。
举个例子:当在程序中生成对象时,正常对象会在年轻代中分配空间,如果是过大的对象也可能会直接在年老代生成(据观测在运行某程序时候每次会生成一个十兆的空间用收发消息,这部分内存就会直接在年老代分配)。年轻代在空间被分配完的时候就会发起内存回收,大部分内存会被回收,一部分幸存的内存会被拷贝至Survivor的from区,经过多次回收以后如果from区内存也分配完毕,就会也发生内存回收然后将剩余的对象拷贝至to区。等到to区也满的时候,就会再次发生内存回收然后把幸存的对象拷贝至年老区。

评分

参与人数 1黑马币 +9 收起 理由
xieshuhua + 9 谢谢啦,真的好详细,我再研究研究.

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马