大家好,我是炸鱼。感觉时间过得真快。Go1.18发布不久,泛型还在如火如荼地进行着。看上次的投票结果,大部分同学还没有在生产环境应用泛型。这不,Go1.19Beta1已经正式发布了。今天,小编就和大家一起看看《Go 1.19 Release Notes》的一些有趣的特辑。内存模型Go的内存模型已经过修改,使Go与C、C++、Java、JavaScript、Rust和Swift使用的内存模型保持一致。Go只提供顺序一致的原子,而不是其他语言中更宽松的形式。另外,随着内存模型的更新,Go1.19在sync/atomic包中引入了新的类型,可以更方便地使用原子值,比如atomic.Int64和atomic.Pointer[T]。Documentation做了以下具体改动:DocumentGo的整体内存模型描述。记录了多词竞争会导致崩溃的情况。记录runtime.SetFinalizer的happens-before。更多同步类型发生前的记录(或链接)。记录同步/原子发生的时间,为C++(以及Java、JavaScript、Rust、Swift、C...)匹配顺序一致的原子。记录不允许的编译器优化。这只是一次“修订”,更改了文档和定义,并不涉及内存模型中的代码更改。为此,RussCox写了三篇关于GoMemoryModel的文章作为系列说明:《Hardware Memory Models》《Programming Language Memory Models》《Updating the Go Memory Model》有兴趣的同学可以看看。文档规范RussCox在提案《Proposal: go/doc: headings, lists, and links in Go doc comments》中添加了对链接、列表和文档注释中更清晰标题的支持。Go1.19文档已更改。下图:旧版(左)和新版(右)的对比。手动粘贴链接变成可跳转:手动分支变成无序列表区分:这是Go文档从古代到新Markdown的一次重大升级。构建约束从Go1.19开始,构建约束unix现在可以在//go:build行中识别,并且可以充当伴随约束。格式如下://go:buildunix注意在1.19版本中,如果GOOS是aix,android,darwin,dragonfly,freebsd,hurd,illumos,ios,linux,netbsd,openbsdorsolaris中的一种,它也满足unix约束。龙芯架构龙芯是一系列各种芯片(包括通用中央处理器、SoC、微控制器、芯片组等)。从Go1.19(GOOS=linux,GOARCH=loong64)开始,在Linux上增加了对龙芯64位架构的支持。前段时间还看到龙芯中科科创板上市,成为国产CPU第一股。国产芯片进入Go语言应该也是中国人推动的,太强了!种族检测Go的种族检测器(racedetector)已经发布到v3版本,将在Go1.19之后投入生产。与v2版本相比,新版本的竞态检测器性能提升了1.5到2倍,使用的内存减少了一半,并支持无限数量的goroutine。注意:目前还不支持windows/amd64和openbsd/amd64。Switch性能改进Go编译器现在使用跳转表来实现大型整数和字符串类型的swicth语句。switch语句的性能改进各不相同,但可以快20%左右。注意:这次只涉及GOARCH=amd64和GOARCH=arm64的变化。运行时堆内存限制较新版本的Go添加了runtime.SetMemoryLimit函数和GOMEMLIMIT环境变量。请注意,runtime.SetMemoryLimit函数为运行时提供软内存限制。函数签名为:funcSetMemoryLimit(limitint64)int64有了这个内存软限制后,Goruntime会遵守这个内存限制。行为包括:调整垃圾回收的频率,更积极地将内存归还给底层系统等,以维持这个软内存限制。此外,即使GOGC=off(或执行SetGCPercent(-1)函数),也会遵守软内存限制。有了内存软限制,在一般场景下,可以有效防止Go进程因为堆内存分配过多而被kill掉,导致Go进程超过最大系统内存资源。漏网之鱼,不可拘束。也就是说它不包括:Go二进制文件使用的空间和Go之外的内存,例如:由底层系统代表进程管理的内存,或由同一进程中的非Go代码管理的内存(CGO)。在新版本的Goroutine栈中,Goruntime会根据goroutine的历史平均栈使用率来分配初始goroutine栈(雾,太糟糕了,Go面试题的答案又要改了。。。)。可以有效避免一些不必要的栈增长和复制,在低于平均水平的情况下最多可以节省2倍的空间浪费。这是一个更详细的优化点。泛型改进Go1.19仍在改进泛型的路上。此更改来自规范《spec: adjust scope of type parameters declared by method receivers》,其中涉及对方法声明中类型参数范围的非常小的更正。原文描述:表示函数类型参数或方法接收者声明的标识符的范围是函数体和函数的所有参数列表。修改说明:表示函数类型参数或方法接收者声明的标识符的范围从函数名之后开始,到函数体结束。在Go1.18中,下面的泛型代码会提示错误:typeT[Tany]struct{}func(T[T])m(){}//error:Tisnotagenerictypewillbecorrectlysupportedin新版本(1.19以后),不会出现编译错误。至于其他通用的进展,它还在修修补补:有待观察。综上所述,在Go1.19的本次新版本更新中,新特性比较少。主要原因是泛型的工作给Go团队带来了很大的工作量。今年,一些大佬相继离职,所以其他新功能的总体可用时间较少。这个版本可以算是一个小版本,填补了一些小“坑”,一些国内面试题的答案也会随之变化。文章持续更新中。可以微信搜索【脑补炸鱼】阅读。本文已收录在GitHubgithub.com/eddycjy/blog中。学习Go语言可以看Go学习地图和路线。欢迎星星提醒。Go书系列Go语言入门系列:Go项目实战Go语言编程之旅初探:以Go为项目深入使用Go语言设计哲学:Go语言进阶之旅:Go语言进阶之旅:深入Go源代码
