首页 > 免root版 > gg修改器有root怎么弄_gg修改器用什么root
gg修改器有root怎么弄_gg修改器用什么root
  • gg修改器有root怎么弄_gg修改器用什么root

  • 大小:14.99MB日期:2024-11-17 15:54:28
  • 语言:简体中文系统:Android
绿色无毒,安全可靠!部分设备误报拦截请通过!

应用详情

GG修改器破解版下载地址:https://ghb2023zs.bj.bcebos.com/d/z/p/d/dbzs.apk?GGXGQ

大家好,今天小编为大家分享关于gg修改器有root怎么弄_gg修改器用什么root的内容,赶快来一起来看看吧。

基础概念

定义: Garbage First,垃圾优先,主要面向服务端应用的垃圾收集器。
开启命令: -XX:+UseG1GC
目标: “停顿时间模型”的收集器:能够支持指定所在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间大概率不超过N毫秒这样的目标。
适用场景: 适用于大内存、多CPU的机器。

设计理念

跳出之前要不收集新生代,要不收集老年代的樊笼,G1面向所有的堆内存任何部分来组成回收集进行回收,衡量标准不再是它属于哪个分代,而是哪块区域中存放的垃圾数量最多,回收效益最大。

区域划分

Region区域

定义: 将Java堆划分为多个大小相等的Region,每个Region都可以是新生代、老年代。G1收集器根据角色的不同采用不同的策略去处理
大小: 2 的N次幂,1MB~32MB
配置参数: -XX:G1HeapRegionSize,不指定G1会根据堆大小自行指定

Humongous区域(Region中的一部分)

定义: 专门用来存储大对象(超过Region容量一半的对象即为大对象),超过整个Region区域的会放在多个连续的Humongous区。
回收身份: G1把Humongous当做老年代的一部分

垃圾收集

借助R大的回答,从最高层看,G1的Collector一侧就是两个大部分,并且这两个部分可以相对独立执行。

全局并发标记(global concurrent marking)

基于SATB(Snapshot At The Begining)形式的并发标记。

1、初始标记(STW)

G1对根进行标记。扫描根集合,标记所有从根集合可直接到达的对象(CMS的初始标记也是类似)并将它们的字段压入扫描栈(marking stack)中等到后续扫描。G1使用外部的bitmap来记录mark信息,而不是用对象头的mark word里的mark bit。在分代式G1模式中,初始标记阶段借用 yong GC的暂停,因而没有额外的、单独的暂停阶段。

为什么初始标记阶段是借用Yong GC的暂停做的?

从逻辑上将“全局并发标记”和“拷贝存活对象”是相对独立的,但是“全局并发标记”阶段的“初始标记”阶段又和Yong GC要做的事情有重叠—遍历根集合,所以在实现上把他们安排在一起做,Yong GC期间可以顺带做,也可以不做。

2、并发标记

G1在整个堆中查找可以访问的(存活的)对象,递归扫描整个堆里的对象图。每扫描到一个对象就对其进行标记,并压入扫描栈中。重复扫描过程直到扫描栈清空。过程中还会扫描SATB 写屏障(write barrier)所记录下的引用,SATB相关下文会介绍。

3、最终/重新标记(STW)

处理在并发标记阶段剩余未处理的SATB写屏障的记录。同时此阶段也进行弱引用处理(reference proccessing),**这个暂停与CMS的remark有一个本质的区别,这个暂停只需要扫描SATB buffer(将这些旧引用作为根重新扫描一遍,避免漏标),而CMS的remark需要重新扫描mod-union table里的dirty card外加整个根集合,**而此时整个Yong 区不管对象死活都会被当做根集合的一部分,因而CMS remark有可能会非常慢。

4、清理(cleanup)(STW)

清点和重置标记状态,与mark-sweep中的sweep阶段类似,但不是在堆上sweep实际对象,而是在marking bitmap里统计每个Region被标记为活的对象有多少。这个阶段如果发现完全没有活对象的Region,就会将其整体回收到可分配Region列表中(空闲列表)。

拷贝存活对象 (Evacuiation)(STW)

也叫筛选回收/清理(STW),负责把一部分Region里的活对象拷贝到空Region里去,然后回收原本的Region的空间。
此阶段可以自由选择任意多个Region来独立收集构成收集集合(Collection Set,CSet),靠每个Region的RSet实现。这是Regional garbage collector的特点。
确定完CSet后肯定就要复制了,其实就和ParallelScavenge的Young GC算法类似,采用并行复制算法把CSet里每个Region里的活对象拷贝到新的Region里,整个过程完全暂停。
“Garbage-First Garbage Collection”论文中讲到,CSet的选定完全靠统计模型找出收益最高、开销不超过用户指定的上限的若干个Region,由于每个Region都有RSet覆盖,要单独evacuate任意一个或者多个Region都没问题。

分代式G1模式下有两种选定CSet的子模式:

可以看到Yong区Region总是在CSet内,因此分代式G1不维护从Yong区Region出发的引用设计的RSet更新。

工作流程总结

分代式G1(只有分代式G1,其它的目前还没有)的正常工作流程就是在YongGC与Mixed GC之间视情况进行切换,背后定期做全局并发标记。初始化标记默认搭在YongGC上执行;
当全局并发标记正在工作时,G1不会选择做Mixed GC,反之MixedGC正在进行中G1也不会启动初始化标记。
在正常的工作流程中没有Full GC的概念,Old区的收集完全靠MixedGC来完成

问题

如何保证收集线程与用户线程互不干扰的运行?

在算法实现细节中说过了“三色标记”算法,这个算法阐明了对象在垃圾收集过程中所有的状态,白、黑、灰。垃圾收集过程中,对象的状态可能会出现黑色对象引用了白色对象或者灰色对象与白色对象之间的引用断开了(当两种条件同时满足时就会出现漏标/错标的情况),其实也就是垃圾收集过程中原有的对象结构被打破了,解决这种情况的方案有两种:增量更新、原始快照,G1 GC使用的是原始快照(SATB),CMS使用的是增量更新(incremental update)

SATB( Snapshot At The Begining)

SATB是维持并发GC正确性的一个手段,抽象的说就是

G1如何知道哪些对象是GC开始后新分配的呢?

每个Region记录着两个TAMS(Top At Mark Start)指针,分别为prevTAMS和nextTAMS,G1在并发标记期间会让新分配的对象在TAMS上分配。在TAMS以上的对象就是新分配的,因而被视为隐式标记

G1的并发标记用了两个bitmap:

对应的每个Region都有这么几个指针:

top是该Region的当前分配指针,[bottom,top)是当前Region已用的部分,[top,end)是尚未使用的可分配空间。

  1. [bottom,preTAMS)这里的对象存活信息可以通过prevBitmap来得知
  2. [prevTAMS,nextTAMS)这部分里的对象在第n-1轮并发标记中隐式存活的
  3. [nextTAMS,top)这部分的对象是在第n轮并发标记中隐式存活的

G1如何处理在并发标记阶段用户线程对对象引用的修改呢?

SATB write barrier,是对“对引用类型字段赋值”这个动作的环切,也就是说赋值前后都在barrier覆盖的范畴内。在赋值前的部分叫做pre-write barrier,在赋值后的叫作post-write barrier。在JVM记忆集文章中我们也讲过,在G1 GC之前其他的垃圾收集器都只是使用了post-write barrier。

SATB要维持“在GC开始时活的对象”的状态这个逻辑snapshot。除了从root出发把整个对象图mark下来之外,其实只需要用pre-write barrier把每次引用关系变化时旧的引用值记下来就好了。这样等并发标记到某个对象时,这个对象的所有引用类型字段的变化全都有记录,就不会漏掉任何在snapshot里活着的对象。当然,很有可能有对象在snapshot中是活的,但是随着并发GC的进行,它已经死了但SATB还是会让它活过这次GC,这时候就会产生floal garbage.

因此在G1 GC中,整个write barrier+oop_field_store是这样的:

void oop_field_store(oop* field, oop new_value) {
pre_write_barrier(field); // pre-write barrier: for maintaining SATB invariant
*field = new_value; // the actual store
post_write_barrier(field, new_value); // post-write barrier: for tracking cross-region reference
}

pre-write barrier的过程如下:

void pre_write_barrier(oop* field) {
oop old_value = *field;
if (old_value != null) {
if ($gc_phase == GC_CONCURRENT_MARK) { // SATB invariant only maintained during concurrent marking
$current_thread->satb_mark_queue->enqueue(old_value);
}
}
}

以上就是关于gg修改器有root怎么弄_gg修改器用什么root的全部内容,感谢大家的浏览观看,如果你喜欢本站的文章可以CTRL+D收藏哦。

相关文章

热门下载

大家还在搜