写点什么

golang 和 java 的性能对比及 golang 内存管理

用户头像
hanaper
关注
发布于: 刚刚
golang和java的性能对比及golang内存管理
  1. golang,java 性能对比

package mainimport "fmt"func main(){  fmt.Println(fibonacci(34))}func fibonacci(i int) int{  if(i<2){    return i;  }  return fibonacci(i-2) + fibonacci(i-1);}
复制代码

先用 Go1.7 看看:

代码如下:

qiangjian@localhost:/works/learnCPP$ go version && time go build fib.go && time ./fibgo version go1.7.5 darwin/amd64real   0m0.206s
user 0m0.165ssys 0m0.059sreal 0m0.052suser 0m0.045ssys 0m0.004s
复制代码

然后,再看看 1.8 的:

代码如下:

qiangjian@localhost:/works/learnCPP$ go18 version && time go18 build fib.go && time ./fibgo version go1.8 darwin/amd64real   0m0.204s
user 0m0.153ssys 0m0.062sreal 0m0.051suser 0m0.045ssys 0m0.003s
复制代码

感觉看不出差异,但官方 1.8 在 GC、Compile 等方面优化提升了 20%,可能是这 demo 太简单了吧。

2. 再来写 Java, 感觉太臃肿了

class Fib{  public  static void main(String[] args){    System.out.println(fibonacci(34));   }   static int fibonacci( int i){    if(i<2) return i;    return fibonacci(i-2) + fibonacci(i-1);  }}
复制代码

编译、运行的结果是:

qiangjian@localhost:/works/learnCPP$ java -version && time javac Fib.java && time java Fib java version "1.8.0_25"Java(TM) SE Runtime Environment (build 1.8.0_25-b17)Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)real  0m0.952suser  0m1.302ssys   0m0.144sreal  0m0.150suser  0m0.123ssys   0m0.025s
复制代码

性能还行, Compile 时间和 c++/go 比就太 low 了。

3. golang 相关网址

4. golang 内存管理

几个关键数据结构

  • mspan 由 mheap 管理的页面,记录了所分配的块大小和起始地址等

  • mcache 与 P(可看做 cpu)绑定的线程级别的本地缓存

  • mcenter 全局空间的缓存,收集了各种大小(67 种)的 span 列表

  • mheap 分配内存的堆分配器,以 8kb 进行页管理

  • fixalloc 固定尺寸的堆外对象空闲列表分配器,用来管理分配器的存储

内存分配逻辑

  • 如果 object size>32KB, 则直接使用 mheap 来分配空间;

  • 如果 object size<16Byte, 则通过 mcache 的 tiny 分配器来分配(tiny 可看作是一个指针 offset);

  • 如果 object size 在上面两者之间,首先尝试通过 sizeclass 对应的分配器分配;

  • 如果 mcache 没有空闲的 span, 则向 mcentral 申请空闲块;

  • 如果 mcentral 也没空闲块,则向 mheap 申请并进行切分;

  • 如果 mheap 也没合适的 span,则向系统申请新的内存空间。

内存回收逻辑

  • 如果 object size>32KB, 直接将 span 返还给 mheap 的自由链;

  • 如果 object size<32KB, 查找 object 对应 sizeclass, 归还到 mcache 自由链;

  • 如果 mcache 自由链过长或内存过大,将部分 span 归还到 mcentral;

  • 如果某个范围的 mspan 都已经归还到 mcentral,则将这部分 mspan 归还到 mheap 页堆;

  • 而 mheap 不会定时将内存归还到系统,但会归还虚拟地址到物理内存的映射关系,当系统需要的时候可以回收这部分内存,否则暂时先留着给 Go 使用。

图解结构关系与内存布局

其他想说明的情况:

其他知识点

  • 标示内存可用的常用两种方法 (1) 将所有可用内存块通过链表连接起来; (2) 通过位图标志;

  • mcentral 中用到的 pad 字段 主要是为了避免 false sharing(伪共享)的性能问题;

  • 内存分配和 tcmalloc 理论类似

用户头像

hanaper

关注

还未添加个人签名 2018.05.07 加入

还未添加个人简介

评论

发布
暂无评论
golang和java的性能对比及golang内存管理