亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何減少 gccgo 編譯的可執行文件所需的虛擬內存?

如何減少 gccgo 編譯的可執行文件所需的虛擬內存?

Go
交互式愛情 2023-05-15 15:21:25
當我使用 gccgo 編譯這個簡單的 hello world 示例時,生成的可執行文件使用了超過 800 MiB 的 VmData。我想知道為什么,如果有什么我可以做的來降低它。睡眠只是為了讓我有時間觀察內存使用情況。來源:package mainimport (  "fmt"  "time")func main() {  fmt.Println("hello world")  time.Sleep(1000000000 * 5)}我用來編譯的腳本:#!/bin/bashTOOLCHAIN_PREFIX=i686-linux-gnuOPTIMIZATION_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}" \   $1gccgo的版本:$ i686-linux-gnu-gccgo-8 --versioni686-linux-gnu-gccgo-8 (Ubuntu 8.2.0-1ubuntu2~18.04) 8.2.0Copyright (C) 2018 Free Software Foundation, Inc.This is free software; see the source for copying conditions.  There is NOwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE./proc/<pid>/status 的輸出:VmPeak:  811692 kBVmSize:  811692 kBVmLck:        0 kBVmPin:        0 kBVmHWM:     5796 kBVmRSS:     5796 kBVmData:  807196 kBVmStk:      132 kBVmExe:     2936 kBVmLib:        0 kBVmPTE:       52 kBVmPMD:        0 kBVmSwap:       0 kB我問是因為我的設備只有 512 MiB 的 RAM。我知道這是虛擬內存,但我想盡可能減少或刪除過度使用。一個簡單的可執行文件需要那么多分配對我來說似乎不合理。
查看完整描述

2 回答

?
慕桂英3389331

TA貢獻2036條經驗 獲得超8個贊

我能夠找到 gccgo 在哪里要求這么多內存。它在 mallocinit 函數的 libgo/go/runtime/malloc.go 文件中:


// If we fail to allocate, try again with a smaller arena.

// This is necessary on Android L where we share a process

// with ART, which reserves virtual memory aggressively.

// In the worst case, fall back to a 0-sized initial arena,

// in the hope that subsequent reservations will succeed.

arenaSizes := [...]uintptr{

  512 << 20,

  256 << 20,

  128 << 20,

  0,

}


for _, arenaSize := range &arenaSizes {

  // SysReserve treats the address we ask for, end, as a hint,

  // not as an absolute requirement. If we ask for the end

  // of the data segment but the operating system requires

  // a little more space before we can start allocating, it will

  // give out a slightly higher pointer. Except QEMU, which

  // is buggy, as usual: it won't adjust the pointer upward.

  // So adjust it upward a little bit ourselves: 1/4 MB to get

  // away from the running binary image and then round up

  // to a MB boundary.

  p = round(getEnd()+(1<<18), 1<<20)

  pSize = bitmapSize + spansSize + arenaSize + _PageSize

  if p <= procBrk && procBrk < p+pSize {

    // Move the start above the brk,

    // leaving some room for future brk

    // expansion.

    p = round(procBrk+(1<<20), 1<<20)

  }

  p = uintptr(sysReserve(unsafe.Pointer(p), pSize, &reserved))

  if p != 0 {

    break

  }

}

if p == 0 {

  throw("runtime: cannot reserve arena virtual address space")

}

有趣的是,如果較大的競技場失敗,它會退回到較小的競技場。因此,限制 go 可執行文件可用的虛擬內存實際上會限制它成功分配的數量。


我能夠使用ulimit -v 327680將虛擬內存限制為較小的數字:


VmPeak:   300772 kB

VmSize:   300772 kB

VmLck:         0 kB

VmPin:         0 kB

VmHWM:      5712 kB

VmRSS:      5712 kB

VmData:   296276 kB

VmStk:       132 kB

VmExe:      2936 kB

VmLib:         0 kB

VmPTE:        56 kB

VmPMD:         0 kB

VmSwap:        0 kB

這些仍然是很大的數字,但是 gccgo 可執行文件可以達到的最好結果。所以問題的答案是,是的,你可以減少 gccgo 編譯的可執行文件的 VmData,但你真的不應該為此擔心。(在 64 位機器上,gccgo 嘗試分配 512 GB。)


查看完整回答
反對 回復 2023-05-15
?
搖曳的薔薇

TA貢獻1793條經驗 獲得超6個贊

可能的原因是您將庫鏈接到代碼中。我的猜測是,如果您要顯式鏈接到靜態庫,那么您將能夠獲得更小的邏輯地址空間,以便將最少的內容添加到您的可執行文件中。無論如何,擁有較大的邏輯地址空間的危害最小。



查看完整回答
反對 回復 2023-05-15
  • 2 回答
  • 0 關注
  • 142 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號