你正在使用的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
运行了一个程序,或者像上面描述的那样修改了源代码。
- setCheckmark在某个时刻被调用
- 在设置
useCheckmark = true
后构建的源代码
你看到了什么?
- 在使用 "as is" 的源代码的情况下,setCheckmark从未被调用。在
gcMarkTermination
内部,useCheckmark被设置为true的时间非常短,所以mgcmark.go中的这行代码永远不会运行
if useCheckmark {
if setCheckmark(obj, base, off, mbits) {
- 当我手动将 useCheckmark = true 时,源代码无法构建。总是会出现致命错误 "fatal error: checkmark found unmarked object"
6条答案
按热度按时间o2g1uqev1#
相关问题和文档
(如果觉得有帮助,请给表情投票;欢迎在 this discussion 中提供更详细的反馈。)
2izufjch2#
cc @golang/runtime @aclements@mknyszek
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
2ledvvac4#
+1 赞同 @prattmic 的观点,直接设置
useCheckmark
不会达到预期效果。这是因为在 checkmark 模式下存在一些内部状态。关于:
当 setCheckmark 没有被调用时
你是如何检查
setCheckmark
是否被调用的?setCheckmark 被设置为 true 的时间窗口非常狭窄
我认为你误解了这段代码的作用。这不是一个狭窄的窗口,实际上它在世界停止运行的同时,有效地运行了一整个单线程的垃圾回收周期。
vxqlmq5t5#
感谢您的反馈,确实存在一个问题。我发现
gcResetMarkState
无法重置根标记作业计数器,因此没有扫描根节点,因此setCheckmark
永远不会被调用。我认为这个问题很容易解决;我会尝试一下。此外,这段代码确实应该至少有一个简单的测试...
noj0wjuj6#
https://go.dev/cl/608915提到了这个问题:
runtime: fix GODEBUG=gccheckmark=1 and add smoke test