首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
beego
V2EX  ›  Go

请教, Go 是如何实现如此夸张的低的内存占用的?

  •  1
     
  •   abcbuzhiming · 132 天前 · 6841 次点击
    这是一个创建于 132 天前的主题,其中的信息可能已经有所发展或是发生改变。
    同样是带有 GC 的语言,Go 的内存占用也太低了点,国外的测试里,同样的功能,Java 都吃到接近 1GB 内存的时候,Go 就十几 MB 的占用;就算不和“家里开矿才能用”的 Java 比,和新锐的 dotnet core 比也有好几倍的差距。我没想明白的是,都是带 GC 的语言,凭什么 Go 就能占这么低的内存?
    36 回复  |  直到 2019-07-30 11:02:12 +08:00
        1
    emeab   132 天前
    go 编译时直接转到机器码
        2
    neoblackcap   132 天前   ♥ 1
    jit 需要内存。至于相同的功能这个说法我表示怀疑。
    GC 其实跟内存用多少关系不大。
        3
    hoyixi   132 天前
    java 首先得要个 JVM
        4
    chenqh   132 天前 via Android
    蛇框架?
        5
    chenqh   132 天前 via Android
    什么框架?
        6
    rrfeng   132 天前
    1. JVM 本身,带 VM 的语言天然就有开销
    2. 设计原因,一个整数类型 Java 里包装了多少层?
    3. 历史包袱,同样功能,Java 可能引入了很多实际上用不到的代码。而 Go 比较年轻,自带库都比较精简。
        7
    micean   132 天前
    啥测试? java 也没这么夸张吧
        8
    reus   132 天前   ♥ 4
    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 不会预先申请很大的内存,释放页也比较积极,所以内存占用相对就低。
        9
    VDimos   132 天前 via Android
    Java 特性那么多,runtime 肯定比 go 费时费内存啊。而且 java 还有层 jvm。java 还有它那........个无穷无尽的调用。。。
        10
    LokiSharp   132 天前
    你确定 Go 写得内个东西功能和 Java 的一样?
        11
    lizhuoli   132 天前 via iPhone
    GC 和内存占用大小关系不大,主要是影响分配和回收的性能。对内存影响大的主要是 JVM,Go 压根没有 VM,不需要这一层来做额外的解释和执行内存占用。这是两个东西
        12
    abcbuzhiming   132 天前
    @emeab 这个理由。。。java 和 dotnet core 是可以强行用 jit 生成机器码的,但是也没见到内存降低多少


    @hoyixi 查了一下 Go 确实没有 virtual machine,但是一个虚拟机的差别有这么大吗?

    @chenqh 无框架,看我下面给的链接

    @micean
    https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/go.html
    看这个测试,绝大部分情况下 Go 的内存占用都吓人的低
        13
    LokiSharp   132 天前
    @abcbuzhiming #12 看起来内存占用差不多啊 Java 虚拟机初始化了差不多 30-40MB,你看 Go CPU 占用都比 Java 高。感觉是默认的 GC 频率比较高吧
        14
    abcbuzhiming   132 天前
    @LokiSharp 你确定你看过了,那个连接里出了 reverse 这一项,其它的项目 java 的内存占用起码都是 go 的几倍起
        15
    realpg   132 天前
    不论什么 JIT 的问题
    golang 出来的是原生程序,还是静态链接的
    还是跟 C/C++ 静态链接的进行一下对比吧

    且不说那些技术的东西

    你执行一个 java 程序
    java -jar xxx
    或者
    java xxx.class

    执行的这个 java 本身就要吃很多内存不是……
        16
    troywinter   132 天前   ♥ 3
    都是 trade off,做过 jvm 的优化就知道了,没什么 go 的方式就优于 java,以大部分人写的代码那点水平,还不如让 java 虚拟机优化的性能。大多数人用 go 写出了 python 的性能。

    内存占用低,不代表性能强,只有内存的数据结构 layout 会和性能相关,和 cpu cache,tlb,llc 相关。我曾经优化过 java 服务,各种指标都大大超过了 native c++的速度,就是得益于 jvm 提供的各种优化,内存也是可以被优化的,但只有你有相对而言足够的利益驱使去做时才值得,如果内存占用在业务领域根本不重要,那有什么意义呢?

    go 和 java 的语言设计思路不一样,go 解决的是谷歌这种级别的大规模工程问题,java 解决的是应用跨平台的问题,两者不是对立关系,哪个适合就用哪个。
        17
    LokiSharp   132 天前
    @abcbuzhiming #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 的几倍呢。。。
        18
    LokiSharp   132 天前
    这两个例子。。。Java 的内存使用是 Go 翻倍但是运行时间却是 Go 的三分之一,综合算下来资源使用并不比 Go 高
        19
    rrfeng   132 天前 via Android   ♥ 5
    楼上优化 Java 达到了 native c++ 代码的速度:请问 c++ 是与你同等领域经验的工程师优化过的吗?
        20
    reus   132 天前
    @LokiSharp regex-redux 慢,是因为用到了 cgo。binary trees 慢,是因为 go 的 GC 比 java 的更频繁,消耗 cpu 更多。基本上 GC 多的程序,go 都比 java 慢,因为 go 偏向低延迟,而不是高吞吐
        21
    reus   132 天前
    @LokiSharp 看 busy 指标,这几个程序里 go 都比 java 高,就是 GC 的消耗多
        22
    niubee1   132 天前
    JVM 你要是不弄块上 G 的内存来跑的话慢得要死
        23
    micean   132 天前
    我把 binary-trees 跑了一次,不带参和带参数-Xmx500m -Xms500m,时间差不多,只是带参的 ygc 次数是不带参的 3 倍。所以只是 gc 策略问题。
    当然 java 占用内存肯定还是比 go 要多一些
        24
    bequt   132 天前
    前段时间还有个 vlang,那个内存更低
        26
    LokiSharp   132 天前 via iPhone
    @reus 为了内存占用消耗这么多 cpu 我觉得划不来😹😹😹
        27
    reus   132 天前
    @LokiSharp 主要是还没有分代,有了分代,GC 可以少消耗一点 CPU。而且主要目的是降低延迟,而不是降低内存占用,现在 go 的 GC 的暂停时间可以低于 0.5ms
        28
    sunwei0325   132 天前
    jvm 的线程栈 Xss 一般都是写死的 1-2M, go 的 goroutine 栈是动态的, 一般 2K 起
        29
    BBCCBB   132 天前
    Jvm 默认会一次性申请一个大内存块, 比如你设置了-Xms1G,那就会一次性申请 1G,

    默认好像是物理内存的 3/8....
        30
    stevenkang   132 天前   ♥ 1
    甲方:我这里有一个需求,评估一下多久能完成?

    18 岁的程序猿:最多五天,尽量三天,最快一天(分分钟开发好,年少轻狂,什么包袱都没有)
    20 岁的程序猿:算上测试这些,预计十五天(改一改 bug,修一修代码)
    25 岁的程序猿:设计、开发、测试,预计三十天(流程规范、顺便摸鱼)
    30 岁的程序猿:调研、设计、评估、开发、测试、交付,预计两个月(启动开发之前先评估成本)

    所以,你说 java 这种嵌套十八层的语言,内存需要多少呢?
        31
    wysnylc   132 天前
    @troywinter #16 有理有据令人信服
        32
    dodo2012   132 天前   ♥ 1
    rust 更低,
        33
    5200   132 天前
    没人注意到楼主的头像吗??
        34
    hangszhang   131 天前
    我是不信有这么大的差距
        35
    wenzhoou   131 天前 via Android
    @5200 头像怎么放大了看?
        36
    no1xsyzy   131 天前
    @abcbuzhiming JIT 不是内存占用更高了?内存里除了运行时还需要载一个编译器,外加字节码和机器码两套码。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2142 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 28ms · UTC 15:25 · PVG 23:25 · LAX 07:25 · JFK 10:25
    ♥ Do have faith in what you're doing.