0%

有多少人工就有多少智能。 ——鲁迅

缘起

众所周知,字节跳动内部主要使用 Thrift,为了更好地掌控生成代码,我们用 Go 自己实现了 Thrift 代码生成工具。

而我们的故(shi)事(gu),正是由一次重构开始……

阅读全文 »

缘起

最近 Go 1.15 发布了,我也第一时间更新了这个版本,毕竟对 Go 的稳定性还是有一些信心的,于是直接在公司上了生产。

结果,上线几分钟,就出现了 OOM,于是 pprof 了一下 heap,然后赶紧回滚,发现某块本应该在一次请求结束时被释放的内存,被保留了下来而且一直在增长,如图(图中的 linkBufferNode):

火焰图

这次上线的变更只有 Go 版本的升级,没有任何其它变动,于是在本地开始测试,发现在本地也能百分百复现。

阅读全文 »

缘起

这几天在重构某段代码后,做了一次性能测试,火焰图中发现了一个十分奇怪的runtime.newobject的调用,大致占用2%,而找遍了整段代码都没有发现有新建对象相关的逻辑。于是迫不得已,祭出了汇编大法,终于定位到了问题所在。这篇文章会使用一段最小可复现的代码来分享这个问题以及背后的原因。

阅读全文 »

最近在研究性能优化的时候,看到了 golang runtime 包下的一个文档HACKING.md觉得颇有意思,读完之后觉得对于 runtime 的理解更上一层,于是想着翻译一下。

本章内容会有一定深度,需要有一定基础的读者,限于篇幅在这里不可能完全展开各个细节。

这一篇文档面向的读者是 runtime 的开发者,所以有很多内容在我们普通使用中是接触不到的。

阅读全文 »

一直在工作中使用 Apache Thrift,但是一直对其中的一些概念一知半解,于是终于抽空学习了一下,记录下来作为学习笔记。

阅读全文 »

在go中,uintptr不能持有对象,unsafe包不安全,但是我之前一直没有时间验证,今天写了段代码验证了一下。

阅读全文 »

最近在golang的邮件列表中看到了一篇关于GC如何处理unsafe.Pointer的讨论,觉得应当记录一下。

阅读全文 »

go语言以并发作为其特性之一,并发必然会带来对于资源的竞争,这时候我们就需要使用go提供的sync.Mutex这把互斥锁来保证临界资源的访问互斥。

既然经常会用这把锁,那么了解一下其内部实现,就能了解这把锁适用什么场景,特性如何了。

阅读全文 »

带GC语言给我们程序的编写带来了极大的便利,但是与此同时屏蔽了很多底层的细节,比如一个对象是在栈上分配还是在堆上分配。对于普通的代码来说虽然不需要关心这么多,但是作为强迫症程序猿,还是希望能让自己写出来的代码性能最优,所以还是需要了解什么是逃逸,以及如何判断是否发生了逃逸。

阅读全文 »