I'm spiderman I'm spiderman
首页
  • 中间件
  • 基础架构
  • 微服务
  • 云原生
  • Java
  • Go
  • PHP
  • Python
  • 计算机网络
  • 操作系统
  • 数据结构
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档

spiderman

快乐学习,快乐编程
首页
  • 中间件
  • 基础架构
  • 微服务
  • 云原生
  • Java
  • Go
  • PHP
  • Python
  • 计算机网络
  • 操作系统
  • 数据结构
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
  • Java

  • Golang

    • golang基本原理
      • golang调度原理
    • PHP

    • Python

    • 计算机语言
    • Golang
    spiderman
    2023-05-02
    目录

    golang基本原理

    # Golang基本原理

    # 局部变量和全局变量

    全局变量存放在静态存储区,位置是固定的。 局部变量在栈空间,栈地址是不固定的

    全局存储区(静态存储区):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后有系统释放。

    常量存储区:这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改

    # 栈,堆,自由存储区

    栈: 就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。 堆: 就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。 自由存储区: 就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。

    # go中的make和new

    make函数是无可替代的,我们在使用slice、map以及channel的时候,还是要使用make进行初始化,然后才才可以对他们进行操作

    # go启动的过程

    启动一个 Go 程序时,首先要经过操作系统的加载,通过可执行文件中 Entry point address 记录的地址,找到 go 程序启动入口: _rt0_amd64 -> rt0_go。rt0_go 中 先进行了 go 程序的 runtime 的初始化,其中包括:调度器,栈,堆内存空间初始化,垃圾回收器的初始化,最后最后通过newproc和mstart调度执行runtime.main,完成一系列初始化过程,再然后才是执行用户的主函数

    # goroutine内存泄漏

    goroutine由于channel的读/写端退出而一直阻塞,导致goroutine一直占用资源,而无法退出 goroutine进入死循环中,导致资源一直无法释放

    解决方法:创建goroutine时就要想好该goroutine该如何结束 使用channel时,要考虑到channel阻塞时协程可能的行为 要注意平时一些常见的goroutine leak的场景,包括:master-worker模式,producer-consumer模式等等。

    # Go 在什么时候会抢占 P?

    如果存在系统调用超时:存在超过 1 个 sysmon tick 周期(至少 20us)的任务,则会从系统调用中抢占 P。

    如果没有空闲的 P:所有的 P 都已经与 M 绑定。需要抢占当前正处于系统调用之,而实际上系统调用并不需要的这个 P 的情况,会将其分配给其它 M 去调度其它 G。

    如果 P 的运行队列里面有等待运行的 G,为了保证 P 的本地队列中的 G 得到及时调度。而自己本身的 P 又忙于系统调用,无暇管理。此时会寻找另外一个 M 来接管 P,从而实现继续调度 G 的目的。

    # goroutine阻塞的原因

    通道(Channel)。 垃圾回收(GC)。 休眠(Sleep) 锁等待(Lock)。 抢占(Preempted)。 IO 阻塞(IO Wait) 其他,例如:panic、finalizer、select 等。

    # Go sync.map 和原生 map 谁的性能好,为什么?

    sync.Map的性能高体现在读操作远多于写操作的时候。 极端情况下,只有读操作时,是普通map的性能的44.3倍。 反过来,如果是全写,没有读,那么sync.Map还不如加普通map+mutex锁呢。只有普通map性能的一半。

    建议使用sync.Map时一定要考虑读定比例。当写操作只占总操作的<=1/10的时候,使用sync.Map性能会明显高很多。

    # go内存逃逸总结:

    1. 函数返回指针型数据
    2. 切片初始化的空间超过限制或者不确定大小
    3. 使用interface{}

    在方法内把局部变量指针返回,被外部引用,其生命周期大于栈,则溢出。 发送指针或带有指针的值到channel,因为编译时候无法知道那个goroutine会在channel接受数据,编译器无法知道什么时候释放。 在一个切片上存储指针或带指针的值。比如[]*string,导致切片内容逃逸,其引用值一直在堆上。 因为切片的append导致超出容量,切片重新分配地址,切片背后的存储基于运行时的数据进行扩充,就会在堆上分配。 在interface类型上调用方法,在Interface调用方法是动态调度的,只有在运行时才知道。

    # slice,len,cap,共享,扩容

    append函数,因为slice底层数据结构是,由数组、len、cap组成,所以,在使用append扩容时,会查看数组后面有没有连续内存快,有就在后面添加,没有就重新生成一个大的素组

    # map如何顺序读取

    map不能顺序读取,是因为他是无序的,想要有序读取,首先的解决的问题就是,把key变为有序,所以可以把key放入切片,对切片进行排序,遍历切片,通过key取值。

    # mutex 饥饿模式

    Go 采用了饥饿模式。即通过判断队头 Goroutine 在超过一定时间后还是得不到资源时,会在 Unlock 释放锁资源时,直接将锁资源交给队头 Goroutine,并且将当前状态改为饥饿模式。

    # mutex 自旋

    一定条件后,mutex 会让当前的 Goroutine 去空转 CPU,在空转完后再次调用 CAS 方法去尝试性的占有锁资源,直到不满足自旋条件,则最终会加入到等待队列里

    自旋的条件如下: 还没自旋超过 4 次 多核处理器 GOMAXPROCS > 1 p 上本地 Goroutine 队列为空 内存空间主要包括:堆,栈

    # Go内存管理过程

    三个组件:用户程序(Mutator)、分配器(Allocator)、收集器(Collector) 首次适应:第一个满足的大小要求的内存块 循环首次遍历:从上一次遍历的地方开始首次适应 最优适应:遍历整个链表,选择最优解 隔离适应:分割成多个链表,每个链表的内存块大小不一样,但是同链表上内存块大小一致,申请时先选择链表,在选择链表上的内存块 go defer(for defer),先进后出,后进先出 Go中的map和slice是引用类型,应该通过值传递 MVCC的目的就是多版本的并发控制,在数据库中的实现,就是为了解决读-写冲突的问题,它的实现原理主要是依赖记录中的 3个隐式字段、undo日志、read view 来实现的

    # 三色标记法 GC

    1. 初始状态全部都是白色
    2. 从root根出发扫描所有根对象,将其标为灰色
    3. 分析灰色是否引用了其他对象,如果没有则标记为黑色;如果有,将其引用标记为灰色,其自身标记为黑色。
    4. 重复步骤3,直至灰色对象队列为空。
    5. 将白色部分的对象视为垃圾,进行回收

    # 调优gc

    减少对象分配,合理重复利用 避免string与[]byte转化 两者发生转换的时候,底层数据结结构会进行复制,因此导致 gc 效率会变低 少用+连接string Go里面string是最基础的类型,是一个只读类型,针对他的每一个操作都会创建一个新的string。 如果是少量小文本拼接,用 “+” 就好;如果是大量小文本拼接,用 strings.Join;如果是大量大文本拼接,用 bytes.Buffer。

    JVM调优
    golang调度原理

    ← JVM调优 golang调度原理→

    最近更新
    01
    innovation create future
    12-13
    02
    RabbitMQ
    12-06
    03
    StarRocks的应用
    09-11
    更多文章>
    Theme by Vdoing | Copyright © 2022-2024 spiderman | 粤ICP备2023019992号-1 | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式