随笔 - 7  文章 - 57  trackbacks - 0
<2011年3月>
272812345
6789101112
13141516171819
20212223242526
272829303112
3456789

常用链接

留言簿(3)

随笔分类

随笔档案

文章分类

文章档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜

 

Q1:为什么程序的数据需要放在堆、栈两个不同(甚至更多)的地方?

 

对于堆和栈中的数据内容来说:

栈:编译器需知道数据内容的生存周期、但是可以快速管理和分配栈内存;

堆:编译器无需知道数据内容的生存周期,保证灵活性、但是分配和回收内存不如把数据放在栈中来得快;

 

Q2:对象在其生命周期结束后经历什么步骤而后被释放?销毁机制具体是怎样的?底层通过什么实现?

 

 

当程序执行到一个块or作用域(scope)的结尾,会自动清理其维护的栈中的内存数据。

于是,如果保存在栈中的唯一reference挂掉了,就意味着再没有办法可以操作其原先引用的对象了。

但是保存在堆中的对象在这时候还没有被清理掉。

 

 

 

对于在堆中,没有被引用的对象。垃圾回收器会直接把他们占据的内存空间释放掉。

真的如书中所说,这种机制滴水不漏吗?会不会有陷阱?

会不会有一些不经意的操作导致引用计数永远不为零,然而用户却懵然不知呢?

内存泄漏真的可以在真正意义上得到避免吗?

 

Q3:垃圾回收机制究竟能干什么,不能干什么?究竟本质是什么?

 

 

垃圾回收机制原来只会对new出来的堆内存起作用!!!

万一不是new出来的,那还是得人工回收……

1、You might not get garbage collected!

哎……这样的垃圾回收机制啊……

还真是懒啊……

 

总之就是,垃圾回收机制只会回收对象在堆中的内存,但究竟这个对象的操作曾经干了什么,有没有“历史遗留问题”,java是一概不管的……

 

 

这个垃圾回收机制还是回到回忆中去吧……(我没吐槽最终幻想,真的没有!)

 

 

ClassName obj//局部对象,放在栈中(C++可以这样,java不行)

C++的好处:作用域结束,局部对象的destructor自动被调用,释放栈中内存;

 

New出来的对象:

//C++的坏处:不执行delete的话,对象占用的内存会一直赖在堆中。就让内存漏一会儿吧。

//java的好处:不用显式执行,只要作用域结束,reference被清除,垃圾回收器就会自动回收堆中的内存;

而且,java兄还不让你在栈中创建局部对象呢……

 

Q3/1那究竟new操作发生的时候,java语言为用户干了什么?new的操作也会对引用计数产生作用——例如初始化和创建吗?垃圾回收器如何工作呢?

 

 

 

相对于堆而言,在栈中释放和分配内存还是效率较高。这可能也是一些程序的数据放在栈中,一些放在堆中的原因之一吧?

 

 

引用计数类似是一个对象中的成员;有东西引用对象,就增加1,当有引用在栈中被释放或者设为NULL,就减少1;发现引用计数为0,就证明这个对象已经没人要了……

缺点:

垃圾回收器要扫描整个对象列表,查找引用计数为0的对象;

如果有两个对象碰巧相互引用了彼此,那这两个对象的引用计数就用不为零,即使没人要也不会被清除掉;

最悲催的是:

JVM都不是通过这种机制实现垃圾回收滴……

 

 

JVM是这么干的……

逆向思维,不找死的,找活的!从一个引用出发,遍历其对象-树(自己作的)。透过每一个在栈中或者在静态区中保存的引用,以之为根节点,遍历由他出发可以到达的对象节点。

好处:

不用遍历所有堆中的对象。

解决两个对象互相引用而导致引用计数恒不为0的问题;

 

 

经过上述处理,没被找到的对象会被清理掉,但是会留下内存碎片,浪费空间。所以……

妙!

把程序停止下来,把活动的对象copy到新的堆内存,连续存放,这样就腾出了那些原先成为碎片的空间。

 

然而,一直copycopy去需要有额外的堆内存来保存copy的数据,实际上copy发生的时候需要双倍于被copy内容的堆内存同时可用。

其次,copy也需要时空开销……

于是……

JVM就把sweep-and-markstop-and-copy结合起来(thinking in java有详述)

大对象占用一个block,每个block有一个generation count作为其可用与否的标记。

一些小对象放在一个block里;

根据引用来遍历其对象-树的操作开始执行:

一般来说,大对象是不会被copy的;

小对象会被复制和重新管理,释放内存碎片;

JVM在碎片多的时候进行stop-and-copy来整理碎片,腾出空间;在堆内存足够和碎片不多的情况下,则只执行sweep-and-mark

 

在这样的垃圾回收机制下,只要是new出来的东西,真的都能回收了。某程度上还真是滴水不漏啊……

 

显然是抄IBM大型机的外存管理嘛!数据集放在block中,被删除的数据集的block标记为不可用,新建的数据集放在后面的block中。当存储空间不够了,整理那些已经存在又可用的数据集,存放在一片连续空间中,把碎片重新整理为可用内存,真是……

抄吧抄吧,不是罪……

 

 

posted on 2011-03-04 20:49 ArthasLee 阅读(777) 评论(1)  编辑 收藏 引用 所属分类: 笔记和疑问

FeedBack:
# re: java学习笔记2——JVM和垃圾回收器 2011-03-21 00:28 陈梓瀚(vczh)
garbage collection is only about memory的意思是说“GC只管内存,不管句柄等资源”……  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理