【发布时间】:2018-12-12 16:36:45
【问题描述】:
当我使用 gccgo 编译这个简单的 hello world 示例时,生成的可执行文件使用了超过 800 MiB 的 VmData。我想知道为什么,如果我能做些什么来降低它。睡眠只是为了给我时间观察内存使用情况。
来源:
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("hello world")
time.Sleep(1000000000 * 5)
}
我用来编译的脚本:
#!/bin/bash
TOOLCHAIN_PREFIX=i686-linux-gnu
OPTIMIZATION_FLAG="-O3"
CGO_ENABLED=1 \
CC=${TOOLCHAIN_PREFIX}-gcc-8 \
CXX=${TOOLCHAIN_PREFIX}-g++-8 \
AR=${TOOLCHAIN_PREFIX}-ar \
GCCGO=${TOOLCHAIN_PREFIX}-gccgo-8 \
CGO_CFLAGS="-g ${OPTIMIZATION_FLAG}" \
CGO_CPPFLAGS="" \
CGO_CXXFLAGS="-g ${OPTIMIZATION_FLAG}" \
CGO_FFLAGS="-g ${OPTIMIZATION_FLAG}" \
CGO_LDFLAGS="-g ${OPTIMIZATION_FLAG}" \
GOOS=linux \
GOARCH=386 \
go build -x \
-compiler=gccgo \
-gccgoflags=all="-static -g ${OPTIMIZATION_FLAG}" \
$1
gccgo的版本:
$ i686-linux-gnu-gccgo-8 --version
i686-linux-gnu-gccgo-8 (Ubuntu 8.2.0-1ubuntu2~18.04) 8.2.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
/proc/
VmPeak: 811692 kB
VmSize: 811692 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 5796 kB
VmRSS: 5796 kB
VmData: 807196 kB
VmStk: 132 kB
VmExe: 2936 kB
VmLib: 0 kB
VmPTE: 52 kB
VmPMD: 0 kB
VmSwap: 0 kB
我问是因为我的设备只有 512 MiB 的 RAM。我知道这是虚拟内存,但我想尽可能减少或删除过度使用。对我来说,一个简单的可执行文件需要这么多分配似乎是不合理的。
【问题讨论】:
-
虚拟内存使用是非常不相关的,将 VmSize 与物理内存进行比较是完全不相关的。居民规模才是真正重要的。
-
@Adrian,这是否意味着可执行文件分配了它并且可能在某些时候使用它?此设备没有交换文件,因此如果可执行文件尝试使用 800 MiB 的 RAM,它将失败。
-
不,它没有。它是“一个进程的虚拟大小,它是它实际使用的内存、它映射到自身的内存(例如 X 服务器的视频卡 RAM)、磁盘上已映射到它的文件的总和(最显着的共享库),以及与其他进程共享的内存。”
-
即使没有页面文件,内存映射文件(包括二进制文件本身和任何加载的共享库)也可以交换到磁盘或从磁盘交换,因为它们已经存在于磁盘上。无需将第二个副本写入交换文件即可在虚拟内存中使用它们。
-
我觉得您一般是在处理虚拟内存,而不是专门针对 VmData,这就是问题所在。你描述的东西是 VmExe 和 VmLib,在这里它们似乎是合理的数字,而不是我的问题的一部分。
标签: linux go virtual-memory gccgo memory-overcommitment