plko345
有 gc 的语言在 gc 过程中是不是都会暂停,这种暂停在什么情况下会难以接受。
如 c c++ rust ,他们在回收内存的过程中会暂停吗?
cubecube
有 gc 基本都会有暂停,但是也存在一些消除暂停的 GC 算法,比如商业的 Zing JVM 。
c rust 不暂停主要是因为自己管内存,用完及时释放了。
iosyyy
cubecube 并不是是因为清除的时候涉及移动对象位置以及对象本身的变化
ql562482472
我记得 java 中 stop the world 是因为它有一刻要遍历所有的对象找到 Root 对象吧
如果没有 root 对象的设计,应该就不会全部暂停
liaohongxing
go 的 gc 已改进到停顿 1ms, 非极端场景基本可忽略 , 到了 1ms 都忍受不了,可以换 c/c++/rust
zmqiang
我印象中,需要暂停的 gc ,是因为运行时需要获取当前内存的使用情况,所以程序逻辑必须暂停。
c c++是手动释放内存的,运行时不参与,所以不存在暂停,各自管各自的就行。并且不需要扫描,哪些内存需要释放是交给程序员决定的
rust 不是很了解,但印象中好像也是不存在 gc 的
go 最新 gc 算法,可以基本避免程序暂停的,是可以实现运行时和程序逻辑并行运行的
bruce0
go 现在只会在开启和关闭内存屏障的时刻会暂停一下, 基本在 1ms 左右, 性能基本可以忽略不计了,
C++智能指针 通过引用计数器做的, 没有 GC 不会有暂停的问题,
rust 不了解, 好像是在编译时期计算得到生命周期 实现内存管理的, 也没有 GC 不会有暂停问题
nicebird
c\c++\rust 手动管理,按需释放。做的一般的,释放过程被离散开了,不会暂停。做的差的,集中释放大量内存,一样会卡住。
Kould
现有的所有垃圾收集算法实际上并不能避免 STW ,而现在只能做到尽可能减少 STW 时间,而有些像 ZGC 这样的就是主打低延迟的垃圾收集器。而 STW 主要影响那种尾部延迟(tail latencies ,多个请求下,响应最慢的请求延迟)比较敏感的服务。ddia 中有这样描述延迟影响的一段话:
“响应时间的高百分位点(也称为 尾部延迟,即 tail latencies )非常重要,因为它们直接影响用户的服务体验。例如亚马逊在描述内部服务的响应时间要求时是以 99.9 百分位点为准,即使它只影响一千个请求中的一个。这是因为请求响应最慢的客户往往也是数据最多的客户,也可以说是最有价值的客户 —— 因为他们掏钱了 [19] 。保证网站响应迅速对于保持客户的满意度非常重要,亚马逊观察到:响应时间增加 100 毫秒,销售量就减少 1% [20] ;而另一些报告说:慢 1 秒钟会让客户满意度指标减少 16% [21 ,22] 。”
而类似 c c++ rust 则属于没有 gc 的语言,需要开发者自己控制内存释放,所以微观来说回收内存会导致指令级的停顿,但是因为开发者有着对对象清晰的结构梳理,在使用得当的情况下则不会导致类似 GC 这样相对来说集中且漫长的延迟(除非你自己整了一套 gc 机制)。
FrankHB
Kould 即使使用得当,不限深度的嵌套数据结构集中释放也很容易出现高延迟的问题。(这不属于使用不当,因为语言允许轻易地构造这种对象。)实际上不容易观察到类似的问题,是因为在此之前,大多数 naive 实现在递归调用释放资源的例程中就直接爆栈了(
Suddoo
JVM 的 gc 暂停时间已经控制在 1ms 以内了、而且也没有什么乱七八糟的参数让二把手们去“调优”了,这个时间对于大部分场景都可以接受,又不是造航天飞机
牺牲了 1ms 的暂停时间,换来开发效率上质的提升,比手动管理内存的语言,降低了手动释放内存的心智负担
cppc
如果你问的 GC 是指这个 https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)
那么 c c++ rust 不存在 GC 这一说,这活得程序员自己干,换句话说,内存的申请、释放在程序代码里体现得清清楚楚。
libook
按我自己的话来说,编程语言视运行时内存管理模式可以划分有 GC 和无 GC 两种,有 GC 就是运行时会自动检测无用的内存数据并释放掉,无 GC 就是开发者决定哪些内存数据什么时候释放掉,不管是显式释放( C 、C++),还是隐式释放( Rust )。
GC 机制本身不一定非要暂停应用,这取决于使用的 GC 算法。
比如一种算法是先标记可达对象,再删除没被标记的对象,那么如果不暂停应用的话,可能在标记和删除操作之间产生了新对象,而这些新对象还没被标记,而删除策略是删除所有未标记对象,就会造成误删。
很多有 GC 机制的语言同时支持多种 GC 算法,具体可以了解一下是不是每种都会暂停应用。
hxtheone
遍历和标记都可以并发操作, 主要是一些 gc 实现里内存压缩这一步, 在清理碎片的过程会导致引用的内存地址变动, 这里的 stw 是省不了的, 要不就换 gc 算法, 要不就不用 gc 自己管理
ksco
推荐阅读此书:垃圾回收算法手册:自动内存管理的艺术
https://book.douban.com/subject/26740958/
字字珠玑。
jhdxr
时代的变迁啊,以前讨论 GC 的时候,拿出来说的基本上都是 java 。现在默认都成 go 了么?
duke807
譬如需要確保實時性的任務,preempt-rt linux 環境,用戶空間寫 c 程序,內存是要在初始化的時候申請好,中途不能釋放內存,也不能申請內存,以保證實時性。
agagega
C++/Rust 释放内存时不会有你想象的那种「暂停」,但如果内存分配器做得不好的话,运行期间也会有大量零散的内存释放,所以有人说这种情况下无 GC 的性能反而不如 GC
12101111
延迟和吞吐量是两回事, 好的 gc 能做到高的吞吐量, 但是 1ms 的延迟说实在还是很高的, 原子引用计数基本上都是纳秒级别的(几百个时钟周期)
sujin190
12101111 #17 原子引用计数单个确实不高,但是明显你忽略了引用计数需要的操作数可是远远超过了 GC 的,引用计数只是不会导致全局暂停延时而已,并不能降低整体延时,甚至是增加延时的
VictorJing94
实时性要求高的时候..........弄 C#遇到过,偶尔程序会卡一下,后面排查发现有人在自旋代码块里加了一句 GC.Collect.......