go 运行时:gccheckmark 什么也不做?

izj3ouym  于 4个月前  发布在  Go
关注(0)|答案(6)|浏览(51)

你正在使用的Go版本是什么( go version )?

$ go version
go version go1.23.0 darwin/amd64

这个问题在最新版本中是否会重现?

你正在使用什么操作系统和处理器架构( go env )?

go env 输出

$ go env
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/Users/mm/Library/Caches/go-build'
GOENV='/Users/mm/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/mm/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/mm/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/darwin_amd64'
GOVCS=''
GOVERSION='go1.23.0'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/mm/Library/Application Support/go/telemetry'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='/usr/bin/clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/Users/mm/go/src/github.com/MikeMitchellWebDev/gc_knobs/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/5y/wtzzmjlj5v52pg7wr8ptbg_m0000gp/T/go-build534087183=/tmp/go-build -gno-record-gcc-switches -fno-common'
uname -v: Darwin Kernel Version 20.6.0: Thu Jul  6 22:12:47 PDT 2023; root:xnu-7195.141.49.702.12~1/RELEASE_X86_64
ProductName:	macOS
ProductVersion:	11.7.10
BuildVersion:	20G1427
lldb --version: lldb-1300.0.42.3
Swift version 5.5.2-dev

你做了什么?

我做了两件事:首先,我用 GODEBUG=gccheckmark=1. 运行了一个程序。当 setCheckmark 没有被调用时,我尝试在手动设置 var useCheckmark = true 后构建go源代码。

你期望看到什么?

这取决于我是否只是用 GODEBUG=gccheckmark=1 运行了一个程序,或者像上面描述的那样修改了源代码。

  1. setCheckmark在某个时刻被调用
  2. 在设置 useCheckmark = true 后构建的源代码

你看到了什么?

  1. 在使用 "as is" 的源代码的情况下,setCheckmark从未被调用。在 gcMarkTermination 内部,useCheckmark被设置为true的时间非常短,所以mgcmark.go中的这行代码永远不会运行
if useCheckmark {
		if setCheckmark(obj, base, off, mbits) {
  1. 当我手动将 useCheckmark = true 时,源代码无法构建。总是会出现致命错误 "fatal error: checkmark found unmarked object"
2izufjch

2izufjch2#

cc @golang/runtime @aclements@mknyszek

guykilcj

guykilcj3#

当我手动设置useCheckmark = true时,源代码无法构建。总是会出现致命错误 "fatal error: checkmark found unmarked object"。我认为这部分并不令人惊讶。请注意,useCheckmark通常仅在每次GC期间临时启用:https://cs.opensource.google/go/go/+/master:src/runtime/mgc.go;l=999-1005;drc=96d8ff00c2d6a88384863a656fb5e53716b614d3;bpv=1;bpt=1

2ledvvac

2ledvvac4#

+1 赞同 @prattmic 的观点,直接设置 useCheckmark 不会达到预期效果。这是因为在 checkmark 模式下存在一些内部状态。
关于:
当 setCheckmark 没有被调用时
你是如何检查 setCheckmark 是否被调用的?
setCheckmark 被设置为 true 的时间窗口非常狭窄
我认为你误解了这段代码的作用。这不是一个狭窄的窗口,实际上它在世界停止运行的同时,有效地运行了一整个单线程的垃圾回收周期。

vxqlmq5t

vxqlmq5t5#

感谢您的反馈,确实存在一个问题。我发现 gcResetMarkState 无法重置根标记作业计数器,因此没有扫描根节点,因此 setCheckmark 永远不会被调用。我认为这个问题很容易解决;我会尝试一下。
此外,这段代码确实应该至少有一个简单的测试...

noj0wjuj

noj0wjuj6#

https://go.dev/cl/608915提到了这个问题:runtime: fix GODEBUG=gccheckmark=1 and add smoke test

相关问题