Golang内存管理 | 青训营笔记

68 阅读3分钟

这是我参与「第五届青训营 」笔记创作活动的第4天

前言

  • 自动内存管理
  • Golang 框架

自动内存管理

基本概念

  • 自动内存管理:由程序语言的运行时系统管理动态内存
  • 避免手动内存管理,专注于实现业务逻辑
  • 保证内存使用的正确性安全性: double-free problem, use-after-free problem
  • 三个任务
    • 为新对象分配空间
    • 找到存活对象
    • 回收死亡对象的内存空间

概念

  • Mutator: 业务线程,分配新对象,修改对象指向关系
  • Collector: GC 线程,找到存活对象,回收死亡对象的内存空间
  • Serial GC: 只有一个 collector
  • Parallel GC: 并行 GC,支持多个 collectors 同时回收的 GC 算法
  • Concurrent GC: 并发 GC,支持 mutator(s) 和 collector(s) 同时执行的 GC 算法

追踪垃圾回收

  • 被回收的条件:不可达对象
  • 过程
    • 标记根对象 (GC roots): 静态变量、全局变量、常量、线程栈等
    • 标记:找到所有可达对象
    • 清理:回收所有不可达对象占据的内存空间

可达性分析算法

  • 通过一系列称为“GC Roots”的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过程所走过的路径称为“引用链”(Reference Chain)
  • 如果某个对象到GC Roots间没有任何引用链相连,或者用图论的话来说就是从GC Roots到这个对象不可达时,则证明此对象是不可能再被使用的。

例如下图,object5,object6,object7到gc root不可达,判定为“可回收”。

引用计数

引用计数,顾名思义,就是给对象加一个引用计数器,每当有对象引用它时,计数器+1;引用失效时,计数器-1。C++的智能指针底层就是引用计数实现的。

  • 每个对象都有一个与之关联的引用数目
  • 对象存活的条件:当且仅当引用数大于 0

缺点

  • 存在循环引用问题

Golang 框架

Hertz

Hertz 是一个 Golang 微服务 HTTP 框架,具有高易用性、高性能、高扩展性等特点。

  • 高易用性
  • 高性能
  • 高扩展性
  • 多协议支持

Kitex

字节跳动内部的 Golang 微服务 RPC 框架,具有高性能强可扩展的特点

  • 高性能
  • 扩展性
  • 多消息协议
  • 多传输协议
  • 多消息类型
  • 服务治理
  • 代码生成

Gorm

顾名思义。

quick start

package main

import (
  "gorm.io/gorm"
  "gorm.io/driver/sqlite"
)

type Product struct {
  gorm.Model
  Code  string
  Price uint
}

func main() {
  db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
  if err != nil {
    panic("failed to connect database")
  }

  // Migrate the schema
  db.AutoMigrate(&Product{})

  // Create
  db.Create(&Product{Code: "D42", Price: 100})

  // Read
  var product Product
  db.First(&product, 1) // find product with integer primary key
  db.First(&product, "code = ?", "D42") // find product with code D42

  // Update - update product's price to 200
  db.Model(&product).Update("Price", 200)
  // Update - update multiple fields
  db.Model(&product).Updates(Product{Price: 200, Code: "F42"}) // non-zero fields
  db.Model(&product).Updates(map[string]interface{}{"Price": 200, "Code": "F42"})

  // Delete - delete product
  db.Delete(&product, 1)
}

参考&鸣谢