Golang 1.8后本身自带了pprof的这个神器,可以帮助我们很方便的对服务做一个比较全面的profile。对于一个Golang的程序,可以从多个方面进行profile,比如memory和CPU两个最基本的指标,也是我们最关注的,同时对特有的goroutine也有运行状况profile。关于golang profiling本身就不做过多的说明,可以从 官方博客 中了解到详细的过程。    Profile的环境    Ubuntu 14.04.4 LTS (GNU/Linux 3.19.0-25-generic x86_64)  go version go1.9.2 linux/amd64     profile的为一个elassticsearch数据导入接口,承担接受上游数据,根据元数据信息写入相应的es索引中。目前的状况是平均每秒是1.3Million的Doc数量。     在增加了profile后,从CPU层面发现几个问题。    runtime mallocgc 占用了17.96%的CPU。 SVG部分图如下                 通过SVG图,可以看到调用链为:   ioutil.ReadAll -> buffer.ReadFrom -> makeSlice -> malloc.go      然后进入ReadAll的源码。     readAll()方法   func readAll(r io.Reader, capacity int64) (b []byte, err error) {  buf := bytes . NewBuffer ( make ([] byte , 0 , capacity ))  // If the buffer overflows, we will get bytes.ErrTooLarge.    // Return that as an error. Any other panic remains.    defer func() {  e := recover ()  if e == nil {  return      }  if panicErr , ok := e .( error ) ; ok && p...
 回顾总结  process and thread   process是操作系统调度的基本单位,一个程序可以理解为一个进程。  thread是process的子process,是process调度的基本单位。    从调度角度理解process和thread    我们知道操作系统调度的时候是以process为单位的,即当我们的程序是单thread的process时,那在这个process获得cpu的时间片时,这个thread能够获得全部的这个时间片。在内核中,我们维护着一个process的table,来记录每个process的基本信息,根据不同的调度方式来使用这个信息或者不使用。    当一个process拥有多个thread时,如何调度thread呢?     当thread为内核态thread时。   当thread为用户态thread时。  混合实现不做讨论      两种情况则有不同的调度方式。当为内核态的thread时,即此时的thread可以称之为轻量级的process,这个时候内核来维护一个thread table和process table相似。同时操作系统来调度thread,就像调度process一样。当为用户态的线程时,那么操作系统感受不到多个thread的存在,因为此时操作系统调度的对象是process,一个process中有多少个thread他不关心,所以当一个process得到CPU时间片后,他会自己来调度thread。    了解他们两个基本工作方式后,应该清楚这两种线程的主要区别:调度者是谁?各个的优缺点是什么?在JAVA中使用的哪种thread?Golang中goroutine是如何对应到我们操作系统的调度单位上去的?    调度者。 内核态的thread:内核。 用户态的thread:process  内核态thread的优点:在单个thread进行syscall而阻塞 时(一个线程不可以即运行代码,又能进行syscall),操作系统可以切换到同process中或者其他process下一个可以执行的thread,而不必阻塞,然而用户态的thread在进行syscall时,整个process下的thread都会阻塞。用户态的thread优点是在进行thread切换时...