Java 垃圾收集器 - 什么时候收集? [英] Java garbage collector - When does it collect?

查看:39
本文介绍了Java 垃圾收集器 - 什么时候收集?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是什么决定了垃圾收集器实际收集的时间?它是在一段时间后还是在一定数量的内存用完后发生?还是有其他因素?

What is it that determines when the garbage collector actually collects? Does it happen after a certain time or after a certain amount of memory have been used up? Or are there other factors?

推荐答案

它在确定需要运行时运行.分代垃圾收集器中的一个常见策略是在第 0 代内存分配失败时运行收集器.也就是说,每次分配一小块内存(大块通常直接放入老"代)时,系统会检查 gen-0 堆中是否有足够的空闲空间,如果没有,则运行GC 来释放空间以便分配成功.然后将旧数据移动到第 1 代堆,当那里的空间用完时,GC 会对其进行收集,将在那里存放时间最长的数据升级到第 2 代堆,依此类推.所以 GC 不只是运行".它可能只在 gen-0 堆上运行(大多数集合都会这样做),或者它可能会检查每一代是否真的需要释放大量内存(这种情况很少需要).

It runs when it determines that it is time to run. A common strategy in generational garbage collectors is to run the collector when an allocation of generation-0 memory fails. That is, every time you allocate a small block of memory (big blocks are typically placed directly into "older" generations), the system checks whether there's enough free space in the gen-0 heap, and if there isn't, it runs the GC to free up space for the allocation to succeed. Old data is then moved to the gen-1 heap, and when space runs out there, the GC runs a collection on that, upgrading the data which has been there longest to the gen-2 heap, and so on. So the GC doesn't just "run". It might run on the gen-0 heap only (and most collections will do just that), or it might check every generation if it really has to free up a lot of memory (which is only necessary fairly rarely).

但这远不是唯一的策略.并发 GC 在后台运行,在程序运行时进行清理.某些 GC 可能会作为每个内存分配的一部分运行.增量收集器可能会这样做,在每次内存分配时扫描一些对象.

But this is far from the only strategy. A concurrent GC runs in the background, cleaning up while the program is running. Some GC's might run as part of every memory allocation. An incremental collector might do that, scanning a few objects at every memory allocation.

垃圾收集器的全部意义在于,它应该只做自己的事情,不需要用户的任何输入.因此,一般而言,您不能也不应该预测它何时会运行.

The entire point in a garbage collector is that it should just do its thing without requiring any input from the user. So in general, you can't, and shouldn't, predict when it'll run.

我相信 Suns JVM 不久前获得了分代 GC(也许是 v1.6?我很久没有编写 Java 代码了,所以不确定,但我记得不久前我很惊讶,当新版本的卖点之一是分代 GC".尤其是因为 .NET 从第一天起就有了.)

其他 JVM 当然可以自由选择他们喜欢的策略.

Other JVM's are of course free to pick whichever strategy they like.

以上关于 Java 和分代 GC 的部分是不正确的.详情见下文:

The above part about Java and generational GC is not true. See below for more details:

1.0 和 1.1 虚拟机使用标记清除收集器,它可以在垃圾收集后对堆进行分段.从 Java 1.2 开始,虚拟机切换到分代收集器,它具有更好的碎片整理行为(请参阅 Java 理论与实践:垃圾收集与性能).

The 1.0 and 1.1 Virtual Machines used a mark-sweep collector, which could fragment the heap after a garbage collection. Starting with Java 1.2, the Virtual Machines switched to a generational collector, which has a much better defragmentation behavior (see Java theory and practice: Garbage collection and performance).

所以 Java 实际上有一个很长一段时间的分代 GC.Java 6 中的新增功能是 Java 6u14 中提供的垃圾优先垃圾收集器 (G1).根据声称在 1.6.0_14 发布的文章:未启用默认情况下.并行收集器仍然是默认的 GC,并且是最高效的 GC,适合普通家庭使用.G1 旨在成为并发收集器的替代品.它旨在提高可预测性,并通过内存区域设计实现快速分配.

So Java actually has a generational GC for ages. What's new in Java 6 is the Garbage-First garbage collector (G1) that is available in Java 6u14. According to the article claiming the release in 1.6.0_14: It is not enabled by default. The parallel collector is still the default GC and is the most efficient GC for common household usage. G1 is meant to be an alternative for the concurrent collector. It is designed to be more predictable and enable fast allocation with memory regions design.

这篇关于Java 垃圾收集器 - 什么时候收集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆