首页 > 其他分享 >Golang 需要注意的知识点

Golang 需要注意的知识点

时间:2023-08-24 11:46:10浏览次数:39  
标签:知识点 内存 Golang 传递 线程 注意 go 切片 指针

云笔记链接地址   go的协程轻量级体现在哪 (1) goroutine 是轻量级的用户态线程,上下文切换代价小

  • go 将 goroutine 的调度维持在用户态
  • 常规线程切换会导致用户态程序代码和内核态操作系统调度程序的切换
  • 只涉及PC(程序计数器,标记当前执行的代码的位置) SP(当前执行的函数堆栈栈顶指针) DX三个寄存器的值的修改; 而对比线程的上下文切换则需要陷入内核模式、以及16个寄存器的刷新
  (2) 内存占用小: 线程栈空间通常是2M, Goroutine 栈空间最小是2k, golang 可以轻松支持1w+的goroutine运行,而线程数量到达1k(此时基本就达到单机瓶颈了), 内存占用就到2G。   new 和 make 区别 参考博客
  • 作用变量类型不同:new 给 string, int, array 分配内存,make 给 slice, map, channel 分配内存;
  • 返回类型不一样:new返回指向变量的指针,make返回变量本身;
  • 处理方式不同:new 分配的空间被置零。make 分配空间后,会进行初始化;
  数组和切片的区别 相同点
  • 只能存储一组相同类型的数据结构
  • 都是通过下标来访问,并且有容量长度,长度通过 len 获取,容量通过 cap 获取
区别
  • 数组是定长,切片长度和容量可以自动扩容
  • 数组是是值类型,切片是引用类型(切片底层指向一个数组)
    Golang指针传递的优点
  • 通过引用类型来传递大的数据结构,可以避免数据结构被复制多次,减少内存的消耗和运行时间的开销。
  • 指针传递还可以用于在函数内部修改参数的值,减少函数之间参数传递的时间和开销
  Go 有没有引用传递 参考链接 值传递:指在调用函数时将实际参数复制一份传递到函数中 引用传递:指在调用函数时将实际参数的地址直接传递到函数中 有个简单的判断方法:看传进去的参数地址变没变,变了就是值传递,没变就是引用传递
  • Go里面没有引用传递,都是值传递。
  • map/channel本身就是指针,是引用类型,所以直接传map和channel本身就可以
  • 在 Go 语言中,引用类型有 切片(slice)、字典(map)、接口(interface)、函数(func) 以及 通道(chan)
  Golang 调度器原理及 GMP 设计思想 基本知识点
  • G:go 协程
  • M:操作系统的工作线程
  • P:go 协程的调度器
  • 全局G队列:存放的也是等待运行的G,当P的本地队列为空时,优先从全局队列获取
  • P的本地队列:存放的也是等待运行的G,不超过256个,如果队列满了,则会把本地队列中一半的G移动到全局队列
  调度器的设计策略
  • 复用线程:避免频繁的创建、销毁线程
    • 工作窃取(work stealing 机制):当本线程无可运行的G时,尝试从其他线程绑定的P偷取G,而不是销毁线程
    • 系统调用 hand off 机制:G进行系统调用阻塞时,线程释放绑定的 P,把 P 转移给其他空闲的线程执行
  • 设置P的数量,提高并行能力
  • 抢占式调度 (一个goroutine最多占用 CPU 10 ms)
    • 1.14 前有局限性,在函数调用中时检查的是否需要抢占
    • 调度器每调度 61 次的时候,都会尝试从全局队列里取出待运行的 goroutine 来运行
    GC-标记清除算法 参考链接
  • 标记清除算法
  • 三色并发标记算法(白色 垃圾、灰色 检查态、黑色 有用)
    • 插入屏障(仅对堆上的数据有效)
      • 插入数据时把数据置为灰色
      • 需要 STW 扫描栈上数据
      • 插入写屏障不对栈生效,需要执行下 STW 的三色标记法(需要 STW 花费时间)
    • 删除屏障
      • 删除了会先变成灰色,下一个周期表成垃圾(回收精度低)
  • 内存回收的触发时间
    • 内存分配量达到阀值触发 gc(每当内存扩大一倍时触发 gc)
    • 定期触发 gc(最长 2 分钟触发 gc)
    • 执行函数触发 gc
  • Gc 性能优化
    • 对象数量越多 GC 压力越大(对象复用,或者大对象组合小对象)
    • 内存逃逸也会增大 GC 压力
    • 参数传递指针也会增加 GC 的压力,不要盲目传递指针
    Root set根节点就是发现堆内存可达数据的一组起点,一般为bss段、数据段以及协程栈对应的元数据   Golang 内存分配 一篇文章把 Go 中的内存分配扒得干干净净
  • mspan:内存管理的基本单位,将页拆分成块来管理
  • mcache:线程的私有资源为单个线程服务
  • mcentral:管理特定规格的 mspan,供线程申请使用
  • mheap:全局管理申请下来的内存
  Golang内存泄漏的7种场景 参考链接 golang pprof实用使用指南(使用 pprof 做性能调试)
  • 传参数组过大,导致内存占用过大
  • 切片截取引起子切片内存泄漏(解决:make 一个新的切片,把数据 copy 过来)
  • Goroutine 阻塞无法退出,导致 goroutine 泄漏
    • 协程阻塞(互斥锁未释放、channel 引起的阻塞)
  • time.Ticker,每隔指定的执行任务,使用完后必须要释放,否则会造成资源浪费
  Go 语言内存逃逸分析 go语言编译器会自动决定把一个变量放在栈还是放在堆,编译器会做逃逸分析(escape analysis),当发现变量的作用域没有跑出函数范围,就可以在栈上,反之则必须分配在堆。 go语言声称这样可以释放程序员关于内存的使用限制,更多的让程序员关注于程序功能逻辑本身 参考链接 go的设计者明明就不希望开发者管这些,但是面试官就偏偏找这种问题问? 醉了也是   参考链接 什么是内存逃逸:一个对象本应该分配在栈上面,结果分配在了堆上面(判断作用域和生命周期在哪里) 内存逃逸的场景:
  • 局部指针返回
  • 栈空间不足
  • 动态类型 interface
  • 闭包引用
  • 向 channel 发送指针数据
  • 在 slice 或 map 中存储指针
  影响:大量的对象从栈逃逸到堆上,增加了GC的压力,在GC的过程中会占用比较大的系统开销(一般可达到CPU容量的25%)              

标签:知识点,内存,Golang,传递,线程,注意,go,切片,指针
From: https://www.cnblogs.com/yweihum/p/17653787.html

相关文章

  • Python-PyMySQL的一些使用注意事项
    一、关于groupby的使用在部分mysql版本(5.7.xx及以上)中,若select的列中,包含了未被groupby的字段,会报以下错误:[Err]1055-Expression#1ofORDERBYclauseisnotinGROUPBYclauseandcontainsnonaggregatedcolumn'xxxx'whichisnotfunctionallydependentoncolu......
  • js知识点学习01
    js知识点学习011.arguements对象(1)什么是arguements对象?由于JavaScript允许函数有不定数目的参数,所以需要一种机制,可以在函数体内部读取所有参数。这就是arguments对象的由来。(2)怎么使用?arguments对象包含了函数运行时的所有参数,arguments[0]就是第一个参数,arguments[......
  • golang中goto跳转语句和跳转标签声明
    和很多其它语言一样,Go也支持goto跳转语句。在一个goto跳转语句中,goto关键字后必须跟随一个表明跳转到何处的跳转标签。我们使用LabelName:这样的形式来声明一个名为LabelName的跳转标签,其中LabelName必须为一个标识符。一个不为空标识符的跳转标签声明后必须被使用至少一次。......
  • 端口映射的注意事项有哪些?
    一、什么是端口映射?在网络中,数据通过端口号来识别和定位特定的设备或服务。通过端口映射,我们可以将公共网络上的请求映射到私有网络内的特定设备或服务上,从而实现对这些设备或服务的远程访问二、如何做端口映射?端口映射一般在路由器中进行设置,在做端口映射之前您先需要知道您的应......
  • python必坑知识点(网络编程)
    1基础1.1作业题1#1.简述二层交换机&路由器&三层交换机的作用。"""二层交换机:构建局域网并实现局域网内数据的转发。路由器:实现跨局域网进行通信。三层交换机:具备二层交换机和路由的功能。"""#2.简述常见词:IP、子网掩码、DHCP、公网IP、端口、域名的作用。""......
  • python必坑知识点(面向对象)
    面向对象的三大特性:封装,继承,多态1三大特性1.1封装将数据或方法放到类里,以供外部调用或自己隐藏#封装原则1、高内聚:高内聚是指一个模块中各个部分之间关联应该是紧密的。2、低耦合:低耦合是指多个模块之间的关联应该是松散的。1.2继承将类中的公共的方法提取到基类中......
  • 真香!基于 Prometheus 的持久化存储,全是知识点
    Prometheus将基于告警规则生成的告警存储为时间序列,不会将Alertmanager的告警信息持久化存储,那么针对历史告警的检索、统计等需求就无法实现。因此需要一种持久化机制用于存储历史告警信息,本文主要探究基于alertmanager告警的开源持久化方案。1.告警触发机制基于主机层面内存......
  • python必坑知识点05
    1、js基本数据类型undefined,null,number,string,symbol,boolean,object,array,date2、js中的拷贝(深浅拷贝)https://www.cnblogs.com/echolun/p/7889848.htmlhttps://www.bilibili.com/video/BV1iu411e7DS/?spm_id_from=333.337.search-card.all.click&vd_source=69181b959bc0......
  • 创建 elastic search 索引的一些注意事项
    在创建Elasticsearch(简称ES)索引时,有多个注意事项需要考虑。以下是一些关键的注意事项,我会通过具体的例子进行详细说明。明确索引需求:在创建索引之前,我们需要对我们的数据和查询需求有清晰的理解。这包括数据的类型(例如文本,数字,日期等)、数据的大小(例如是否有大量的数据需要被......
  • 写专利中需要注意的地方
    1、visio直接复制粘贴到word中,在word中使用ctrl+shift+F9转化为图片,点击图片后右击,选择图片颜色选择灰度 2.公式一定要用word中的写 ......