Go语言的内存占用是多少?

huangapple go评论76阅读模式
英文:

What is Go's memory footprint

问题

这篇关于Dropbox从Go语言转向Rust语言的文章中提到,Dropbox在构建其MagicPocket产品时发现Go语言的"内存占用"(memory footprint)过高,无法满足公司构建的大规模存储系统的需求。

问题:Go语言的"内存占用"具体是指什么(它是从哪里产生的,如何衡量,是否与垃圾回收、二进制大小有关,它是否总是较高),为什么它比Rust语言的内存占用更高?

英文:

This article on Wired about Dropbox's switch from Go to Rust for its MagicPocket product says

> “memory footprint”—the amount of computer memory it demands while running Magic Pocket—was too high for the massive storage systems the company was trying to build.

Question(s): What exactly is Go's "memory footprint" (where does it come from, how is it measured etc, is it related to garbage collection,binary size, is it something that will always be high) and why is it higher than Rust's?

答案1

得分: 4

"它占用了很高的内存"只是另一种说法,意思是他们的程序使用了大量的RAM。这与垃圾回收有关,因为垃圾回收的程序只会定期释放内存(因为每个垃圾回收周期都需要CPU时间),而手动内存管理往往会在不再使用内存时立即释放内存。

手动内存管理的缺点要么是错误可能会导致崩溃和安全漏洞(例如在C++中,您可能会在内存被重新用于其他内容后意外使用已释放的变量),要么是您必须努力表达每个变量、引用等的确切生命周期,以便编译器可以检查它们是否以有效的方式使用(例如在Rust中,您与借用检查器交互,以排除代码中可能不正确使用内存的情况)。


Wired的报道中的句子让人觉得"内存占用"是一个可以分配给任何语言的简单可测量的数量(而你的问题将这个想法推向了逻辑的极致)。事实并非如此简单。在不同的语言中,执行不同的操作在内存、性能等方面的成本是不同的,你必须了解语言/运行时的细节,才能知道语言在给定类型的程序中的工作方式。

例如,CPython使用引用计数,在更短的时间内释放未使用的内存,但代价是需要存储和更新引用计数。Java一方面有一些像对象头这样的东西,每个对象都会增加一定量的内存开销,但使用一些技巧来加速垃圾回收(如分代收集),而Go则没有(至少目前没有)。或者在Go中,您可以尝试通过使用自由池来回收内存,并根据kostya的说法调整GOGC以更频繁地释放未使用的内存,以减少程序的内存占用。

更重要的是,并不是我列出的那些具体细节非常重要,而是除了"更高的内存占用"或"更低的内存占用"之外,还有很多细节需要考虑。


所以:"内存占用"指的是特定工作负载下特定程序占用的RAM数量。更大的问题是,在像你、我或Dropbox团队这样的人需要考虑的一系列权衡中,它只是其中一个因素。

英文:

"It had a high memory footprint" is just another way to say their program used a lot of RAM. It is related to garbage collection in that GC'd programs only free memory periodically (because each GC cycle takes CPU time), whereas manual memory management tends to free memory more or less as soon as it's unused.

The downside of manual memory management is either that mistakes can cause crashes and security bugs (as in C++, where you can accidentally use a freed variable after the memory has been reused for something else) or you have to put effort into expressing the exact lifetimes of each variable, reference, etc. in your code so that the compiler can check that they're being used in a valid way (as in Rust, where you interact with the borrow checker to root out potentially incorrect uses of memory in your code).


The sentence in the Wired story makes it sound like "memory footprint" is a simple measurable quantity you could assign to any language (and your question takes that idea to its logical conclusion). It's not quite that simple. In different languages, doing different things has different costs in memory, performance, and so on, and you kind of have to understand languages'/runtimes' details to know how the language will work with a given sort of program.

For example, CPython has reference counting, and that frees unused memory sooner but at the cost of having to store and update reference counts. Java has, on the one hand, things like object headers that add a certain amount of memory overhead per object, but uses some tricks to speed garbage collection (like generational collection) that Go doesn't (yet). Or in Go, you might try to reduce the memory footprint of a program by recycling memory with free pools and adjusting GOGC to free unused memory more often as kostya said.

The bigger point there is not that those specific details I listed are super important, but that there can be a lot of details to consider other than "higher memory footprint" or "lower memory footprint."


So: "memory footprint" refers to the amount of RAM a particular program with a particular workload takes up. Bigger picture, it's one factor in a large set of tradeoffs that folks like you or I or Dropbox's team have to navigate.

答案2

得分: 1

垃圾收集器需要有可用的空闲内存才能高效工作。默认情况下,Go应用程序需要的内存大约是活动数据集(应用程序对象占用的内存)大小的两倍。

可以使用GOGC环境变量进行调整。将其设置为较低的值,应用程序将从操作系统请求较少的内存,但垃圾收集器将更频繁地运行,因此会使用更多的CPU资源。将其设置为较高的值,垃圾收集器将更少地运行并且使用更少的资源,但应用程序的"内存占用"将更高。

这是一个一般的想法,但确切的内存、性能需求和GOGC的影响在很大程度上取决于应用程序的特定情况。

英文:

The garbage collector requires free memory to be available to work efficiently. By default Go application needs roughly twice as much memory as size of live data set (memory occupied by application objects).

This can be tuned using GOGC environment variable. By setting it to a lower value the application will request less memory from OS but GC will run more frequently therefore will use more CPU resources. By setting it to a higher value the GC will run less frequently and use less resources but the application will have higher "memory footprint".

This is general idea but the exact memory, performance requirements and GOGC effect are highly application specific.

huangapple
  • 本文由 发表于 2016年3月15日 09:11:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/36000978.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定