JVM GC一个对象的朝生夕死
2017-09-11 23:58
197 查看
一,假如活在一个没有分代的连续内存中
假设程序占用的内存是从0000~FFFF这个地址,现在程序执行到给一个对象分配内存的那部分代码,给这个对象分配了2345~2346这段内存,程序继续执行,到了某一个时刻,程序分配的内存地址用完了,这时候,程序要回收这段地址里面,已经无用的对象,那么,它首先要从头到尾扫描一遍,然后把其中没用的地址空间找到,之后将对象占用地址的起始位置和终止位置进行一个向上或者向下的移动,将不连续的地址变成连续的地址空间,打扫房间结束,程序继续分配内存执行程序;在一整块连续的内存中,进行所有对象的分配,方式是比较简单的,但是就是每次都要从头到尾的扫描一遍,如果程序占用的内存非常大,或者程序需要对外部响应非常及时,这时候,就会出现很大的问题了。二,two part
将可用内存分为:常回收内存部分+不常回收部分。按照对象是否经常被回收进行分配内存。对象创建之后,先放入常常进行垃圾回收的内存空间中,如果好久不释放,再放入不常回收的部分。需要制定一个标准或者规则,来定义多久对象从常回收部分移动到不常被回收的部分。这部分主要是为了说明为什么要分代回收。
三,s0,s1 Eden部分
这三部分都属于新生代,对象被创建之后,首先放入Eden中,经过一次Minor GC,被放入From Survivor,再次Minor GC,想象你此时身处From Survivor中,你身边有着经历过16此Minor GC还活着的老对象,它们被移动到了老年代中,还有像你似的,只经历过一两次的,你们一起被复制到了To Survivor中,最后,From Survivor空了,Eden也空了,之后,To Survivor连续整齐的排列着熬下来还属于青年的新生代对象,From Survivor与To进行交换,此时,你又回到了From survivor中,静静地等着下一个时钟周期的到来。。
四,s部分作用
如果没有s部分,每次新创建的对象,先被放到Eden,满了之后,放到老年代,老年代满了,full gc,你会发现,full gc其实是很频繁的,为了不经常对老年代进行回收,就要把年轻代里面对象的回收,做的过程久一点,放入到老年代的条件严格一点儿,所以加入一个中间缓冲带S。五,s0与s1
试想如果仅有s,在某个对新生代回收的时刻,这时候,在Eden与S部分,都有不连续的内存空间,合并之后,空间还是不连续的,有时候可能会出现这种情况,给一个对象分配空间,总的剩余容量是足够的,但是没有连续的空间可以达到对象的大小,这就尴尬了。所以,为了减少这种碎碎念的出现,s拆分为s0,s1,两部分采用复制算法进行对象交换,保证了在某个时刻,一个s是空的,另一个空间是连续的。相关文章推荐
- Delphi LiveBindings如何绑定一个对象(转)
- java使用compareTo实现一个类的对象之间比较大小
- javascript 构建一个xmlhttp对象池合理创建和使用xmlhttp对象
- 将前端所要传的参数设置在一个对象中,将对象转换成字符串往后台传
- C++中创建一个对象
- 一个对象实例化过程
- js的三大家族(offset/scroll/client)和一个事件对象(event)///正则
- 读书笔记 effective c++ Item 21 当你必须返回一个对象的时候,不要尝试返回引用
- 对象中key-value的value怎么再放一个对象
- AngularJS一个由于未声明对象而报的错
- 将一个js对象装换为一个JSON串
- 使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
- ceph中如何查找一个对象或者rbd image 的实际存储位置
- javascript 遍历一个对象object 有时会用到(转自:http://blog.csdn.net/peng_wu01/article/details/5569247)
- iOS 通过HEX(十六进制)得到一个UIColor的对象
- Java 对象之间的比较,判断两个对象的某一个属性相等,则对象相等
- 被一个丢失的对象搞蠢了
- JavaScript声明一个对象的三种方式
- 遍历一个对象并执行其中的方法
- Java单例设计模式(实现Java的一个类只有一个对象)