golang和java的性能对比及golang内存管理
golang,java性能对比
package main import "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 ./fib go version go1.7.5 darwin/amd64real 0m0.206s user 0m0.165s sys 0m0.059s real 0m0.052s user 0m0.045s sys 0m0.004s 然后,再看看1.8的:
代码如下:
qiangjian@localhost:/works/learnCPP$ go18 version && time go18 build fib.go && time ./fib go version go1.8 darwin/amd64real 0m0.204s user 0m0.153s sys 0m0.062s real 0m0.051s user 0m0.045s sys 0m0.003s
感觉看不出差异,但官方1.8在GC、Compile等方面优化提升了20%,可能是这demo太简单了吧。
再来写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.952s user 0m1.302s sys 0m0.144s real 0m0.150s user 0m0.123s sys 0m0.025s
性能还行, Compile时间和c++/go比就太low了。
golang相关网址
Go语言官方网址
官网里面新手推荐看:A Tour of Go(Go语言编程指南)(中文版本在这里: Go 指南):主要是带你了解基础的Go语言和使用方法,重点是有个在线编译器,可以在浏览器里面写Go语言,直观感受Go语言;
How to Write Go Code:也是带你入门学习Go语言的,类似教程吧,英文的,新手同样可以看;
https://golang.org/ref/spec:Go编程语言的参考手册,英文的;
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理论类似