请教,Golang Go语言是如何实现如此夸张的低内存占用的?
请教,Golang Go语言是如何实现如此夸张的低内存占用的?
同样是带有 GC 的语言,Go 的内存占用也太低了点,国外的测试里,同样的功能,Java 都吃到接近 1GB 内存的时候,Go 就十几 MB 的占用;就算不和“家里开矿才能用”的 Java 比,和新锐的 dotnet core 比也有好几倍的差距。我没想明白的是,都是带 GC 的语言,凭什么 Go 就能占这么低的内存?
jit 需要内存。至于相同的功能这个说法我表示怀疑。
GC 其实跟内存用多少关系不大。
java 首先得要个 JVM
蛇框架?
什么框架?
- JVM 本身,带 VM 的语言天然就有开销
2. 设计原因,一个整数类型 Java 里包装了多少层?
3. 历史包袱,同样功能,Java 可能引入了很多实际上用不到的代码。而 Go 比较年轻,自带库都比较精简。
啥测试? java 也没这么夸张吧
java 是虚拟机,天然就多占内存,再加上没有值类型,很多数据结构都不是紧凑布局的
.net core 同理
go 的自动 GC 相对于非自动 GC,多使用的内存主要是 GC bitmap,这部分是 2bit 对应堆里的 64bit,也就是 512GB 的堆全分配满的话,GC bitmap 就会有 16GB,三十二分之一的 overhead。
另外,GC 算法不同,占内存也会不同。会复制对象的 GC,在复制过程里就需要占用额外的内存。java 的 CMS, G1 都是 copying GC。zgc 暂时不做复制。
还有个影响因素是向 os 申请页和释放页回 os 的策略。如果虚拟机选择一开始就申请很大的内存,那占用自然高。释放慢,也会高。go 不会预先申请很大的内存,释放页也比较积极,所以内存占用相对就低。
Java 特性那么多,runtime 肯定比 go 费时费内存啊。而且 java 还有层 jvm。java 还有它那…个无穷无尽的调用。。。
你确定 Go 写得内个东西功能和 Java 的一样?
GC 和内存占用大小关系不大,主要是影响分配和回收的性能。对内存影响大的主要是 JVM,Go 压根没有 VM,不需要这一层来做额外的解释和执行内存占用。这是两个东西
这个理由。。。java 和 dotnet core 是可以强行用 jit 生成机器码的,但是也没见到内存降低多少
查了一下 Go 确实没有 virtual machine,但是一个虚拟机的差别有这么大吗?
无框架,看我下面给的链接
https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/go.html
看这个测试,绝大部分情况下 Go 的内存占用都吓人的低
#12 看起来内存占用差不多啊 Java 虚拟机初始化了差不多 30-40MB,你看 Go CPU 占用都比 Java 高。感觉是默认的 GC 频率比较高吧
你确定你看过了,那个连接里出了 reverse 这一项,其它的项目 java 的内存占用起码都是 go 的几倍起
不论什么 JIT 的问题
golang 出来的是原生程序,还是静态链接的
还是跟 C/C++ 静态链接的进行一下对比吧
且不说那些技术的东西
你执行一个 java 程序
java -jar xxx
或者
java xxx.class
执行的这个 java 本身就要吃很多内存不是……
都是 trade off,做过 jvm 的优化就知道了,没什么 go 的方式就优于 java,以大部分人写的代码那点水平,还不如让 java 虚拟机优化的性能。大多数人用 go 写出了 python 的性能。
内存占用低,不代表性能强,只有内存的数据结构 layout 会和性能相关,和 cpu cache,tlb,llc 相关。我曾经优化过 java 服务,各种指标都大大超过了 native c++的速度,就是得益于 jvm 提供的各种优化,内存也是可以被优化的,但只有你有相对而言足够的利益驱使去做时才值得,如果内存占用在业务领域根本不重要,那有什么意义呢?
go 和 java 的语言设计思路不一样,go 解决的是谷歌这种级别的大规模工程问题,java 解决的是应用跨平台的问题,两者不是对立关系,哪个适合就用哪个。
#14
regex-redux
source secs mem gz busy cpu load
Go
29.20 399,668 802 61.29 71% 55% 37% 47%
Java
10.48 645,680 740 31.62 72% 87% 74% 68%
binary-trees
source secs mem gz busy cpu load
Go
25.25 374,780 1013 87.65 87% 88% 86% 86%
Java
8.28 907,060 835 27.59 86% 90% 80% 77%
额。。。哪你咋不说 Go 的运行时间是 Java 的几倍呢。。。
这两个例子。。。Java 的内存使用是 Go 翻倍但是运行时间却是 Go 的三分之一,综合算下来资源使用并不比 Go 高
楼上优化 Java 达到了 native c++ 代码的速度:请问 c++ 是与你同等领域经验的工程师优化过的吗?
JVM 你要是不弄块上 G 的内存来跑的话慢得要死
我把 binary-trees 跑了一次,不带参和带参数-Xmx500m -Xms500m,时间差不多,只是带参的 ygc 次数是不带参的 3 倍。所以只是 gc 策略问题。
当然 java 占用内存肯定还是比 go 要多一些
前段时间还有个 vlang,那个内存更低
为了内存占用消耗这么多 cpu 我觉得划不来😹😹😹
主要是还没有分代,有了分代,GC 可以少消耗一点 CPU。而且主要目的是降低延迟,而不是降低内存占用,现在 go 的 GC 的暂停时间可以低于 0.5ms
jvm 的线程栈 Xss 一般都是写死的 1-2M, go 的 goroutine 栈是动态的, 一般 2K 起
Jvm 默认会一次性申请一个大内存块, 比如你设置了-Xms1G,那就会一次性申请 1G,
默认好像是物理内存的 3/8…
甲方:我这里有一个需求,评估一下多久能完成?
18 岁的程序猿:最多五天,尽量三天,最快一天(分分钟开发好,年少轻狂,什么包袱都没有)
20 岁的程序猿:算上测试这些,预计十五天(改一改 bug,修一修代码)
25 岁的程序猿:设计、开发、测试,预计三十天(流程规范、顺便摸鱼)
30 岁的程序猿:调研、设计、评估、开发、测试、交付,预计两个月(启动开发之前先评估成本)
所以,你说 java 这种嵌套十八层的语言,内存需要多少呢?
#16 有理有据令人信服
rust 更低,
没人注意到楼主的头像吗??
我是不信有这么大的差距
头像怎么放大了看?
JIT 不是内存占用更高了?内存里除了运行时还需要载一个编译器,外加字节码和机器码两套码。
Java 默认是空间换时间
golang 更倾向于小内存占用
在Golang(Go语言)中,其低内存占用的实现得益于多种设计哲学和编译时、运行时的优化策略。以下是一些关键因素:
-
垃圾回收机制:Go语言内置了高效的垃圾回收器,采用并发标记-清除算法,减少了内存泄漏和碎片化的风险,同时尽量降低了对程序运行的影响。这种机制使得开发者无需手动管理内存,从而减少了内存管理错误,并优化了内存使用。
-
编译时优化:Go编译器在编译阶段进行了大量的优化工作,如内联函数、消除未使用的变量、循环展开等,这些优化减少了运行时的内存占用和CPU开销。
-
值传递与逃逸分析:Go语言中的函数参数默认是值传递,但编译器会通过逃逸分析来确定哪些变量需要在堆上分配,哪些可以在栈上分配。栈上分配的内存会自动回收,从而降低了内存管理的复杂性。
-
内存对齐与紧凑的数据结构:Go语言的数据结构在设计时考虑了内存对齐和紧凑性,减少了内存浪费。同时,通过接口和类型断言等机制,实现了灵活且高效的数据处理。
-
简洁的标准库:Go语言的标准库设计简洁而高效,避免了不必要的内存占用。同时,标准库中的许多函数都经过了精心优化,以确保最佳的性能和内存使用。
综上所述,Go语言通过一系列精心设计的机制和优化策略,实现了低内存占用的特性。这使得Go语言在高性能、高并发等场景下具有显著的优势。