各位游戏大佬大家好,今天小编为大家分享关于gg修改器免root防崩溃_Gg修改器免root的内容,轻松修改游戏数据,赶快来一起来看看吧。
有很多文章描述了一个拙劣的垃圾收集器是如何让应用程序濒临崩溃,不能满足承诺的服务等级协议(SLA)。例如,一段不可预测的漫长的垃圾收集停顿时间可能会轻易地超过其他高性能应用程序的响应时间要求。此外,当你使用一个非整理型的垃圾收集器(GC)时,就会增加堆内存的不规则性。例如,并发标记-清除(CMS)收集器会尝试通过一次串行的(也就是单线程的)完整垃圾收集(Full GC)来回收碎片化的堆内存,而这个过程会带来 STW(Stop The World)停顿时间。
现在,我们可以对以上段落进行扩展:假设年轻代发生了一次内存分配失败,那么便会触发一次年轻代垃圾收集,导致某些对象被晋升至老年代。更进一步地,假设碎片化的老年代没有足够的空间用来容纳最近晋升的对象。这种情况将会触发一次 Full GC 周期,此时便会整理堆内存。
当使用 CMS GC 时,Full GC 是串行的,并且会带来 STW 停顿时间。因此,在整个 Full GC 期间,你的应用程序线程将会停止运行,等待收集器完成堆内存空间的回收和整理工作。STW 停顿的持续时间取决于堆内存的大小和幸存对象的数量。
另外,即使你想要通过并行(也就是多线程的)整理来解决碎片化的问题,你仍然不能避免发生一次 Full GC(这个过程涉及 Java 堆内存的所有分代),而此时堆内存已经够用了,只需要从老年代回收一部分空闲空间即可。
当使用 Parallel Old 垃圾收集器时,这是一个常见的场景。使用 Parallel Old 来回收老年代的内存可能会带来 STW 停顿时间,在此期间会并行执行 Full GC。这种 Full GC 并不是增量的,它会带来一段漫长的 STW 停顿时间,不能和应用程序交错执行。
注意:你可以从此处获得更多关于 HotSpot 垃圾收集的信息。
在了解以上信息之后,我们将考虑一种名为“垃圾优先”(G1)收集器的解决方案,这是 HotSpot 最新的垃圾收集器(JDK 7u4 版本开始引入的)。
G1 垃圾收集器是一种增量型的收集器,具有并行整理内存碎片的功能。相比起 CMS 收集器和 Parallel Old 收集器,G1 收集器能够提供更加可预测的停顿时间。通过引入一个并行的、多阶段的并发标记周期,G1 收集器能够处理更大的堆内存,并且在最坏情况下还能够提供合理的停顿时间。使用 G1 收集器的基本思路就是设置你的堆内存范围(使用 -Xms
选项设置最小堆,使用 -Xmx 选项设置最大堆)和一个现实可行的(软实时)停顿时间目标(使用 -XX:MaxGCPauseMillis 选项),然后就让垃圾收集器自己完成工作。
传统的 GC 内存布局会将一块连续的 Java 堆内存分割成(连续的)年轻代和老年代。在引入 G1 收集器之后,HotSpot 便抛弃了这种内存布局方式。在 G1 收集器中,HotSpot 引入了“区域(Region)”的概念。一块大容量的连续的 Java 堆内存空间被分割成多个固定大小的堆内存区域。有一个“空闲”区域列表负责维护这些区域。随着需求的增加,空闲区域就会被分配给年轻代或老年代。这些区域的大小在 1MB 至 32MB 之间,取决于你的 Java 堆内存的总大小。我们的目标是将整个堆内存分割成大约 2048 个区域。某个区域一旦释放完成,它便会回到“空闲”区域列表之中。G1 收集器的原理就是尽可能多地(同时尽力满足停顿时间目标)回收 Java 堆内存,G1 会收集存活数据总量最少的区域,也就是优先收集垃圾最多的区域。因此,这种收集器才取名为“垃圾优先”垃圾收集器。
图-1:传统的 GC 内存布局
在使用 G1 收集器时,需要注意一件事情:不管年轻代,还是老年代,它们都不是连续的内存空间。这是一个非常方便的特性,因为现在可以更加动态地调整分代的大小。
自适应大小的 GC 算法,诸如 Parallel Old 收集器,最终会保留额外的内存空间,堆内存的每个年代可能需要用来适应其连续空间的约束。如果使用 CMS 收集器,那么就需要进行一次 Full GC,以便于调整 Java 堆内存和各个分代的大小。
相反,G1 收集器使用逻辑年代(年轻代和老年代是由非连续的区域集合组成的)的概念,这样就不会浪费太多的空间或时间。
可以肯定的是,G1 收集器的算法确实利用了 HotSpot 的某些基本概念。例如,内存分配的概念、将对象拷贝至 Survivor 区的概念,以及将对象晋升至老年代的概念,这些概念类似于 HotSpot 先前实现的垃圾收集器。Eden 区域和 Survivor 区域仍然能构成年轻代。除了为“巨型”对象分配内存之外,大多数对象都是在 Eden 区中分配内存的。(注意:对于 G1 收集器来说,如果对象体积大于等于区域容量的一半,那么这个对象就被称为“巨型对象”,应当直接在老年代的“巨型”区域中分配内存。)G1 收集器会根据你的停顿时间目标来选择一个自适应的年轻代大小。年轻代的大小可以在预设的最小值和预设的最大值之间,它和 Java 堆内存的大小存在函数关系。当 Eden 区达到容量时,G1 就会执行一次“年轻代垃圾收集”,此时便会带来一段“排空停顿时间”。在这段 STW 停顿时间之内,G1 会将存活对象从构成 Eden 区的区域之中拷贝(排空)至构成名为“to-space”的Survivor 区的区域之中。
图-2:垃圾优先收集器的内存布局
除此之外,根据对象的年龄和“老年化阈值”,G1 会将构成名为“from-space”的 Survivor 区的区域之中的存活对象拷贝至构成名为“to-space”的 Survivor 区的区域之中,或者晋升至构成老年代的区域之中。
每次年轻代垃圾收集都包含并行工作的时间,以及顺序/串行工作的时间。为了进一步说明这一点,本文将演示 G1 垃圾收集器的一段日志输出,采用 JDK 7u25 版本。
以下命令行选项会产生此后的 GC 日志输出:
java –Xmx1G –Xms1G –XX:+UseG1GC –XX:+PrintGCDetails –XX:+PrintGCTimeStamps GCTestBench
注意:本文使用默认的停顿时间,也就是 200ms。
0.189: [GC pause (young), 0.00080776 secs]
[Parallel Time: 0.4 ms]
[GC Worker Start (ms): 188.7 188.7 188.8 188.8
Avg: 188.8, Min: 188.7, Max: 188.8, Diff: 0.1]
[Ext Root Scanning (ms): 0.2 0.2 0.2 0.1
Avg: 0.2, Min: 0.1, Max: 0.2, Diff: 0.1]
[Update RS (ms): 0.0 0.0 0.0 0.0
Avg: 0.0, Min: 0.0, Max: 0.0, Diff: 0.0]
[Processed Buffers : 0 0 0 1
Sum: 1, Avg: 0, Min: 0, Max: 1, Diff: 1]
[Scan RS (ms): 0.0 0.0 0.0 0.0
Avg: 0.0, Min: 0.0, Max: 0.0, Diff: 0.0]
[Object Copy (ms): 0.2 0.2 0.1 0.2
Avg: 0.2, Min: 0.1, Max: 0.2, Diff: 0.0]
[Termination (ms): 0.0 0.0 0.0 0.0
Avg: 0.0, Min: 0.0, Max: 0.0, Diff: 0.0]
[Termination Attempts : 1 2 1 2
Sum: 6, Avg: 1, Min: 1, Max: 2, Diff: 1]
[GC Worker End (ms): 189.1 189.1 189.1 189.1
Avg: 189.1, Min: 189.1, Max: 189.1, Diff: 0.0]
[GC Worker (ms): 0.4 0.4 0.3 0.3
Avg: 0.4, Min: 0.3, Max: 0.4, Diff: 0.1]
[GC Worker Other (ms): 0.0 0.0 0.1 0.1
Avg: 0.1, Min: 0.0, Max: 0.1, Diff: 0.1]
[Clear CT: 0.2 ms]
[Other: 0.2 ms]
[Choose CSet: 0.0 ms]
[Ref Proc: 0.2 ms]
[Ref Enq: 0.0 ms]
[Free CSet: 0.0 ms]
日志缩进可以区分并行和顺序的工作分组。并行工作时间可以进一步分割成:
1. External Root Scanning
并行收集器的工作线程用于扫描外部根引用(例如:寄存器、线程栈等指向收集集合(CSet)的引用)所耗费的时间。
2. Update Remembered Sets (RSets)
RSet 可以帮助 G1 收集器追踪指向某个区域的引用。此处显示的时间是并行工作线程用于更新 RSet 所耗费的时间总量。
3. Processed Buffers
这个计数显示了工作线程处理了多少次“更新缓冲区”。
4. Scan RSets
这段时间用于扫描 RSet,查找指向某个区域的引用。这段时间的长度将取决于 RSet 数据结构的“粒度”。
5. Object Copy
在每次年轻代垃圾收集期间,收集器会将 Eden 区和名为“from-space”的 Survivor 区之中的所有存活对象拷贝至名为“to-space”的 Survivor 区或老年代之中。此处会列出工作线程完成这项任务所耗费的时间总量。
6. Termination
每个工作线程在完成它们的特定工作(例如:对象扫描和复制)之后,便会进入自己的“终止协议”。每个工作线程在终止运行之前会查找其他线程是否还有尚未完成的工作;如果有,那么就帮助其他线程完成工作;如果没有,那么就终止运行。此处列出的时间表示工作线程用于“终止协议”所耗费的时间。
7. Parallel worker ‘Other’ time
工作线程会执行一些其他的操作,这些操作没有被记入上述的任何一个并行操作之中,此处列出的就是这些操作耗费的时间。
顺序工作(每项工作都可以独立地并行化执行)可以被分割成:
1. Clear CT
垃圾收集器的工作线程用于清除扫描元数据的 RSet 的卡表(Card Table)所耗费的时间。
2. Other
一些其他工作所耗费的时间:
Choose Collection Set (CSet):一次垃圾收集周期会收集 CSet 中的区域集合。在垃圾收集的停顿时间之内,G1 会收集/排空特定 CSet 中的所有存活数据。此处列出的时间是用于最终确定需要添加至 CSet 的区域集合所耗费的时间。
Reference Processing:用于处理从先前的垃圾收集阶段推迟处理的引用(软引用(Soft)、弱引用(Weak)、最终引用(Final)和虚引用(Phantom))所耗费的时间。
Reference En-queuing:将引用放进未处理列表所耗费的时间。
Free CSet:释放刚刚收集的区域集合的内存空间所耗费的时间。这段时间也包含释放区域的 RSet 所耗费的时间。
我们刚刚已经对很多概念有了初步的了解,例如:RSet、RSet粒度、更新缓冲区、CSet。在接下来的几个段落中,我们还会学习更多的概念,例如:初始快照(SATB)算法和屏障,等等。然而,为了更加深入地学习这些概念,我们就不得不深入研究 G1 收集器的内部原理,虽然这是一个很有趣的话题,但是超出了本文的范围。
现在,我们已经知道年轻代垃圾收集是如何开始填满老年代的,我们还需要引入(和理解)一个名为“标记阈值”的概念。当堆内存总量的占用率超过这个阈值时,G1 收集器将触发一次多阶段的并发标记周期。用来设置这个阈值的命令行选项是 –XX:InitiatingHeapOccupancyPercent ,它的默认值是 Java 堆内存总量的 45%。G1 收集器使用一种名为“初始快照(SATB)”的标记算法,它会在标记周期的“初始”阶段为堆内存中的存活对象集合创建一个逻辑快照。这种算法会使用写前屏障来记录和标记作为逻辑快照的组成部分的对象。现在,我们可以花费一些时间来讨论多阶段并发标记的各个阶段。首先,我们要查看 G1 收集器的日志输出:
0.078: [GC pause (young) (initial-mark), 0.00262460 secs]
[Parallel Time: 2.3 ms]
[GC Worker Start (ms): 78.1 78.2 78.2 78.2
Avg: 78.2, Min: 78.1, Max: 78.2, Diff: 0.1]
[Ext Root Scanning (ms): 0.2 0.1 0.2 0.1
Avg: 0.2, Min: 0.1, Max: 0.2, Diff: 0.1]
[Update RS (ms): 0.2 0.2 0.2 0.2
Avg: 0.2, Min: 0.2, Max: 0.2, Diff: 0.0]
[Processed Buffers : 2 3 2 2
Sum: 9, Avg: 2, Min: 2, Max: 3, Diff: 1]
[Scan RS (ms): 0.0 0.0 0.0 0.0
Avg: 0.0, Min: 0.0, Max: 0.0, Diff: 0.0]
[Object Copy (ms): 1.8 1.8 1.8 1.8
Avg: 1.8, Min: 1.8, Max: 1.8, Diff: 0.0]
[Termination (ms): 0.0 0.0 0.0 0.0
Avg: 0.0, Min: 0.0, Max: 0.0, Diff: 0.0]
[Termination Attempts : 1 1 1 1
Sum: 4, Avg: 1, Min: 1, Max: 1, Diff: 0]
[GC Worker End (ms): 80.4 80.4 80.4 80.4
Avg: 80.4, Min: 80.4, Max: 80.4, Diff: 0.0]
[GC Worker (ms): 2.2 2.2 2.2 2.2
Avg: 2.2, Min: 2.2, Max: 2.2, Diff: 0.1]
[GC Worker Other (ms): 0.0 0.1 0.1 0.1
Avg: 0.1, Min: 0.0, Max: 0.1, Diff: 0.1]
[Clear CT: 0.2 ms]
[Other: 0.2 ms]
[Choose CSet: 0.0 ms]
[Ref Proc: 0.1 ms]
[Ref Enq: 0.0 ms]
[Free CSet: 0.0 ms]
[Eden: 3072K(5120K)->0B(5120K) Survivors: 1024K->1024K Heap: 16M(32M)->16M(32M)]
[Times: user=0.06 sys=0.00, real=0.00 secs]
0.081: [GC concurrent-root-region-scan-start]
0.082: [GC concurrent-root-region-scan-end, 0.0009122]
0.082: [GC concurrent-mark-start]
<snip> [Zero or more embedded young garbage collections are possible here,
but removed for brevity.]
0.094: [GC concurrent-mark-end, 0.0115579 sec]
0.094: [GC remark 0.094: [GC ref-proc, 0.0000033 secs], 0.0004374 secs]
[Times: user=0.00 sys=0.00, real=0.00 secs]
0.094: [GC cleanup 22M->10M(32M), 0.0003031 secs]
[Times: user=0.00 sys=0.00, real=0.00 secs]
0.095: [GC concurrent-cleanup-start]
0.095: [GC concurrent-cleanup-end, 0.0000350]
另外,每个阶段的解释,如下所述:
初始标记阶段:在初始标记阶段期间,G1 收集器会标记根引用。这就是上述日志输出的第一行想要告诉我们的信息。初始标记阶段会伴随一次普通(STW)的年轻代垃圾收集同时执行。因此,这个阶段的日志输出类似于你在年轻代排空停顿期间看到的日志。
根区域扫描阶段:在这个阶段期间,G1 收集器会扫描初始标记阶段的 Survivor 区域,查找指向老年代对象的引用,然后标记这些引用指向的对象。这个阶段是和应用程序并发运行的,不会产生 STW 停顿时间。注意,这个阶段会在下一次年轻代垃圾收集发生之前运行完成。
并发标记阶段:在这个阶段期间,G1 收集器会在整个 Java 堆内存中查找可达(存活)对象。这个阶段会和应用程序一起并发运行,并且年轻代垃圾收集可以中断并发标记阶段(如上述日志所示)。
重新标记阶段:重新标记阶段有助于完成对象标记工作。在这段 STW 停顿期间,G1 收集器会排空任何余留的 SATB 缓冲区,并且会追踪任何尚未访问过的存活对象。在重新标记阶段期间,G1 收集器还会进行引用处理。
清除阶段:这是多阶段标记周期的最后一个阶段。当 G1 收集器进行存活度计算(以便于标识完全空闲的区域,以及混杂着垃圾的区域,这些区域是垃圾收集的候选区域)时,以及当 G1 收集器清除 RSet 时,这部分时间就会产生 STW 停顿。当 G1 收集器复位,并且将清空的区域返回至空闲列表之中时,这部分时间就是并发运行的。
一旦 G1 收集器成功地完成并发标记周期,它就具备启动老年代垃圾收集所需要的相关信息。直到现在,还是不能对老年代的区域进行垃圾收集,因为 G1 收集器尚不具备任何与这些区域相关联的标记信息。由于 G1 收集器不仅对 Eden 区和 Survivor 区的区域进行垃圾收集,而且还会(可选地)添加老年代的区域进行混合垃圾收集,这种垃圾收集方式有助于老年代的碎片整理和区域排空,因此被恰当地称为“混合”垃圾收集。现在,我们将讨论一些重要的细节,以便于理解混合垃圾收集。
混合垃圾收集通常是由多个混合垃圾收集周期组成。当收集了足够数量的老年代区域时,G1 收集器会再次执行年轻代垃圾收集,直至下一次标记周期完成。有一些命令行选项能够控制添加至 CSet 的老年代区域的精确数量,如下所示:
–XX:G1MixedGCLiveThresholdPercent:老年代区域中的存活对象的占用率阈值,这些区域会包含在混合垃圾收集之中。
–XX:G1HeapWastePercent:你能够忍受的堆内存中的垃圾占用率阈值。
–XX:G1MixedGCCountTarget:对老年代区域执行混合垃圾收集的目标次数,这些区域的存活数据的占用率不会超过 G1MixedGCLiveThresholdPercent 选项设定的值。
–XX:G1OldCSetRegionThresholdPercent:在一次混合垃圾收集期间,可以收集的老年代区域的最大数量的限制。
我们可以看一下 G1 收集器的混合垃圾收集周期的日志输出:
1.269: [GC pause (mixed), 0.00373874 secs]
[Parallel Time: 3.0 ms]
[GC Worker Start (ms): 1268.9 1268.9 1268.9 1268.9
Avg: 1268.9, Min: 1268.9, Max: 1268.9, Diff: 0.0]
[Ext Root Scanning (ms): 0.2 0.2 0.2 0.1
Avg: 0.2, Min: 0.1, Max: 0.2, Diff: 0.1]
[Update RS (ms): 0.0 0.0 0.0 0.0
Avg: 0.0, Min: 0.0, Max: 0.0, Diff: 0.0]
[Processed Buffers : 0 0 0 1
Sum: 1, Avg: 0, Min: 0, Max: 1, Diff: 1]
[Scan RS (ms): 0.1 0.0 0.0 0.1
Avg: 0.1, Min: 0.0, Max: 0.1, Diff: 0.1]
[Object Copy (ms): 2.6 2.7 2.7 2.6
Avg: 2.7, Min: 2.6, Max: 2.7, Diff: 0.1]
[Termination (ms): 0.1 0.1 0.0 0.1
Avg: 0.0, Min: 0.0, Max: 0.1, Diff: 0.1]
[Termination Attempts : 2 1 2 2
Sum: 7, Avg: 1, Min: 1, Max: 2, Diff: 1]
[GC Worker End (ms): 1271.9 1271.9 1271.9 1271.9
Avg: 1271.9, Min: 1271.9, Max: 1271.9, Diff: 0.0]
[GC Worker (ms): 3.0 3.0 3.0 2.9
Avg: 3.0, Min: 2.9, Max: 3.0, Diff: 0.0]
[GC Worker Other (ms): 0.1 0.1 0.1 0.1
Avg: 0.1, Min: 0.1, Max: 0.1, Diff: 0.0]
[Clear CT: 0.1 ms]
[Other: 0.6 ms]
[Choose CSet: 0.0 ms]
[Ref Proc: 0.1 ms]
[Ref Enq: 0.0 ms]
[Free CSet: 0.3 ms]
总而言之,通过引入构成逻辑分代的区域(Region)的概念,G1 收集器的性能要优于先前的垃圾收集器。G1 收集器可以对老年代进行增量收集,而区域能够提供更细的粒度。G1 通过复制存活数据来完成绝大部分的回收工作,从而实现了内存碎片整理。相对于不具备碎片整理功能的空间回收技术来说,这种方式明显迈进了一大步,使得老年代看起来就像是瑞士奶酪一样!
在(多阶段标记周期的)清理阶段期间,会发生第一级内存回收,此时 G1 收集器将回收能够完全释放(例如:充满垃圾)的区域,然后将这些区域返回至空闲列表之中。在增量的混合垃圾收集期间,会发生下一级内存回收。如果两级回收都失败了,那么就会对整个 Java 堆内存进行垃圾收集。这就是众所周知的完整垃圾收集(Full GC),这是收集器的一种安全失败(Fail-Safe)机制。
上述的所有措施大大简化了老年代的内存回收,使得 G1 能够以一种分层的方式进行垃圾收集。
我希望这篇文章有助于读者初步了解 G1 收集器的不同之处和基本构成。感谢您的阅读!
以上就是关于gg修改器免root防崩溃_Gg修改器免root的全部内容,游戏大佬们学会了吗?
免root玩gg修改器_gg修改器免root怎么用 分类:免root版 1,406人在玩 各位游戏大佬大家好,今天小编为大家分享关于免root玩gg修改器_gg修改器免root怎么用的内容,轻松修改游戏数据,赶快来一起来看看吧。 星标 02-15 为了开通更多的系统,新手玩家就……
下载用gg修改器怎么设置root,如何使用GG修改器设置Root权限 分类:免root版 184人在玩 如果你想要在安卓设备上享受更多的自由和定制性,那么获取Root权限是一个不错的选择。而GG修改器是一款非常好用的工具,通过它可以轻松地为你的设备设置Root权限。 下载GG修改器 ……
下载不root用不了gg修改器么_gg修改器怎么不用root修改 分类:免root版 1,708人在玩 各位游戏大佬大家好,今天小编为大家分享关于不root用不了gg修改器么_gg修改器怎么不用root修改的内容,轻松修改游戏数据,赶快来一起来看看吧。 一、问题描述 邮件(Microsoft Outl……
下载如何下载gg修改器的root,如何下载gg修改器的root一款优秀的软件下载工具 分类:免root版 153人在玩 在现代社会,软件已经成为人们日常工作和生活中不可或缺的一部分。随着网络技术的发展,越来越多的软件涌现出来,但是找到自己需要的软件并进行下载却是一件非常麻烦的事情。为了解……
下载怎样用gg修改器root_怎样用GG修改器修改现代战舰 分类:免root版 1,726人在玩 各位游戏大佬大家好,今天小编为大家分享关于怎样用gg修改器root_怎样用GG修改器修改现代战舰的内容,轻松修改游戏数据,赶快来一起来看看吧。 上次发过一篇文章,很多人还是不怎么……
下载gg修改器真正免root下载_gg修改器免root版下载教程 分类:免root版 2,049人在玩 各位游戏大佬大家好,今天小编为大家分享关于gg修改器真正免root下载_gg修改器免root版下载教程的内容,轻松修改游戏数据,赶快来一起来看看吧。 作者:刻薄哥 众所周知,小米在近……
下载gg修改器的root是啥意思 分类:免root版 1,932人在玩 各位游戏大佬大家好,今天小编为大家分享关于gg修改器的root是啥意思的内容,轻松修改游戏数据,赶快来一起来看看吧。 支付会收到root后不安全警告 3.root后,手机内部的参数设置……
下载免root怎么用gg修改器_GG修改器怎么免root 分类:免root版 941人在玩 各位游戏大佬大家好,今天小编为大家分享关于免root怎么用gg修改器_GG修改器怎么免root的内容,轻松修改游戏数据,赶快来一起来看看吧。 智能手机向来是年轻人的“刚需”,而随着互联……
下载GG修改器有免root_专用GG修改器 分类:免root版 1,890人在玩 各位游戏大佬大家好,今天小编为大家分享关于GG修改器有免root_专用GG修改器的内容,轻松修改游戏数据,赶快来一起来看看吧。 语音技术哪家强?就在中国来说,讯飞还是非常顶尖的。……
下载如何将gg修改器root_GG修改器怎么修改 分类:免root版 1,113人在玩 各位游戏大佬大家好,今天小编为大家分享关于如何将gg修改器root_GG修改器怎么修改的内容,轻松修改游戏数据,赶快来一起来看看吧。 [IT168试客] ROOT是一种存在于UNIX系统和类UNIX……
下载