go runtime和java jvm
go runtime和java jvm之间的共同点就是GC,通过两者的对比,可以更加深入理解两者。
go runtime 和java jvm对比
Go | JAVA | |
---|---|---|
线程进程 | go协程 | Java线程进程 |
GC | go gc | JVM gc |
内存 | Tcmalloc | 对象 |
go协程vsJava线程
go在用户态实现了调度模块,每个go协程的Contex大小仅2k,远小于操作系统进程的Contex大小,在上下文切换的时候需要切换的内容小,调度不需要经过用户态内核态切换,速度远快操作系统进程,并且可以轻易的支持单机万以上规模的量级的go协程数量。
原理上GPM的模型,可以参见文章https://zhuanlan.zhihu.com/p/111370792
其中G是Goroutine队列,P是Processor,是逻辑概念,M是Machine,和Kernel对应。另外有个负责调度的Goroutine,根据一定的算法对P进行调度,M和P是N:M的关系。
GC
Java gc
java运行在虚拟机上,需要按照冯诺依曼图来理解虚拟机。对于linux系统,其目标对象是汇编(机器码),而JAVA则是字节码。
JAVA通过编译器将java文件编译为字节码文件,在虚拟机中各有classLoader的外部系统,将字节码加载到虚拟机中。加载过程有
-------------Load-> 检验 ->初始化->卸载
等过程,需要特别理解其中初始化的过程。
对于JVM,需要理解虚拟机的结构
image.png
理解虚拟机的结构后,我们主要要理解堆的分区,堆分为老年区和Yong区,其中Yong表示为:
image.png
学习JVM首先要理解上述基本概念,JVM的GC管理就是管理堆,有不同的算法,主要满足的目标是SWT和吞吐率。
涉及到算法有:
- 标记清除
- 复制整理
- 根路径清除
垃圾回收器有:
image.png
而我们对GC的调优就是设置JVM的各种参数,达到JVM调优的目标。
Go GC 三色标记法
Go就不涉及调优问题,GC就是runtime实现
三色标记法的流程如下,它将对象通过白、灰、黑进行标记,参考下图3的动图过程:
所有对象最开始都是白色.
- 从 root 开始找到所有可达对象,标记为灰色,放入待处理队列。
- 遍历灰色对象队列,将其引用对象标记为灰色放入待处理队列,自身标记为黑色。
- 循环步骤3直到灰色队列为空为止,此时所有引用对象都被标记为黑色,所有不可达的对象依然为白色,白色的就是需要进行回收的对象。
三色标记法相对于普通标记清扫,减少了 STW 时间. 这主要得益于标记过程是 "on-the-fly" 的,在标记过程中是不需要 STW 的,它与程序是并发执行的,这就大大缩短了 STW 的时间.
小结
JVM这种底层的东西,一般都比较难以学习,因为绝大部分人真正工作的时候是用不到GC调优的,但是对于一门语言学习,理解其基础还是非常重要的。通过与go对比,我们能更深入的理解相关的基础知识。