您的位置:首页 > 游戏 > 游戏 > 有的网页打不开是怎么回事_东莞seo优化团队_北京培训机构_十大免费网站推广

有的网页打不开是怎么回事_东莞seo优化团队_北京培训机构_十大免费网站推广

2024/12/22 9:22:04 来源:https://blog.csdn.net/2202_76092586/article/details/144569736  浏览:    关键词:有的网页打不开是怎么回事_东莞seo优化团队_北京培训机构_十大免费网站推广
有的网页打不开是怎么回事_东莞seo优化团队_北京培训机构_十大免费网站推广

垃圾回收机制,是java对于内存自动回收的机制。但是呢,这不是java独创的。


GC回收的是内存,更准确的来说是对象,回收的是堆上的内存。

那么释放哪几块内存区呢?

1)程序计数器(不需要进行额外的回收,线程销毁,自然就回收了)。

2)栈(不需要进行额外的回收 ,线程销毁,自然就回收了)。

3)元数据区(一般也不需要,都是加载类,很少卸载类)。

4)堆(GC回收的主力部分)(这里我们主要回收的就是对象,new出来的都是在堆中的)。

GC的流程主要有两个步骤:

1. 找到谁是垃圾。

2. 释放所对应的内存。


GC机制的两种实现方法


引用计数法


这里的引用计数法并不用jvm采取的方案,但这里的引用计数法非常的简单。

例如,当我们创建对象是如:Test a = new Test() , 这里对象本身的计数器就会加一。

当我们再写一个 Test b = a 时,这里我们的计数器就会再加一,变成2。

如图解:

当我们都将a 和 b 置为空是,这里的计数器就减一减一,变成零。

如图:

引用计数变成零,这里就可以视作为垃圾了。

但是这个方法有两个缺陷:

(1)消耗额外的存储空间(如果你的对象比较大还好,但如果你的对象比较小,且数目比较多的话,那么消耗的额外空间就比较多了)

(2)循环引用的问题(比较重要)


循环引用问题解释:

如代码:

class Test{Test t;
}Test a = new Test();Test b = new Test();a.t = b;b.t = a;a = null;b = null;

如上图代码,a和b的引用都被引用了两次,计数器上的数字为2。

但当我们,对a和b赋值为空的时候,计数器都减一,变成一,但这里就可以视作为垃圾释放了,但计数器为一,释放不掉,就会出现问题了。

如图:

所以两个引用相互指向对方,外面的代码也无法访问到,就会出现这种问题。


可达性分析(JVM采取的方案)


可达性分析呢,解决了存储空间的问题,也解决了循环引用的问题 

JVM把对象之间的引用关系,理解成了树形的结构。

JVM就会不停的遍历这样的结构,能遍历到的标记为可达,不能被标记到的标记为不可达。

这里就像是数据结构中的,从根节点触发,所有的叶子节点都是可达的。

如果后续叶子节点没有遍历到,那么就是不可达的了。

如果根节点为空了,那么都是不可达的了,那么全都视为垃圾了。


还有这里的树型结构是自己创建的,本身就存在的,不是虚构的。

如图:


释放垃圾的策略


(1)标记清除


标记清除就是把对应垃圾的对象所对应的内存释放,简单粗暴。

如图:

这样的有什么后果呢,从图中可以分析,释放垃圾后,会存在大量的内存碎片。

当我们后面创建对象时,需要申请一大块空间时,就会影响到。

所以这种算法并不实用。


(2)复制算法


这里的复制算法,比如,我们的一段内存空间,有的是垃圾,那么我们会把不是垃圾的对象所对应的内存,复制到另一块的内存空间上,然后对原来的一块内存,全部释放掉。

如图:

释放后:

这里最大的问题就是,空间浪费的太多了。


(3)标记整理


这里的标记清理,类似于搬运,就是一块空间,垃圾释放掉之后,会把不是垃圾的放到一块。

如图:

这样的处理方法解决了时间的问题,但是时间开销更大了。


基于上述的这三种策略,又有了一个更复杂的策略。分代回收。


分代回收


分代算法和上面讲的3种算法不同,分代算法是通过区域划分,实现不同区域和不同的垃圾回收策 略,从而实现更好的垃圾回收。这就好比中国的⼀国两制方针⼀样,对于不同的情况和地域设置更符合当地的规则,从而实现更好的管理,这就时分代算法的设计思想。

当前JVM垃圾收集都采用的是"分代收集(Generational Collection)"算法,这个算法并没有新思想, 只是根据对象存活周期的不同将内存划分为几块。一般是把Java堆分为新生代和老年代。在新生代 中,每次垃圾回收都有大批对象死去,只有少量存活,因此我们采用复制算法;而老年代中对象存活率高、没有额外空间对它进行分配担保,就必须采用"标记-清理"或者"标记-整理"算法。

如图:

(1)伊甸区 ->生存区 通过复制算法。(由于存活对象很少, 复制开销也很低, 生存区空间也不必很大)。
(2)生存区 ->另一个生存区 通过复制算法,没经过一轮 GC,生存区中都会淘汰掉一批对象,剩下的通过复制算法,进入到另一个生存区(进入另一个生存区的还有从伊甸区里进来的对象)。
存活下来的对象,年龄 +1
(3)生存区 -> 老年代 某些对象, 经历了很多轮 GC, 都没有成为垃圾,就会复制到 老年代 ~~


老年代的对象,也是需要进行 GC 的,但是老年代的对象生命周期都比较常,就可以降低 GC扫描的频率。上述的过程就是分代回收的基本算法逻辑。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com