1月19日Go学习笔记|青训营笔记

73 阅读2分钟

性能优化以及自动内存管理

这是我参与【第五届青训营】伴学笔记创作活动的第四天

性能优化,优化哪里?

一个产品的性能优化非常重要,好的产品才能够被用户所接受。倘若产品的性能优化非常差劲,页面跳转卡顿,那么它必然是市场的淘汰品。So,性能优化,优化在哪个方面呢?

  • 业务层优化:针对特定场景,具体问题,具体分析,容易获得较大性能收益
  • 语言运行时优化:解决更通用的性能问题,会考虑到更多场景,Tradeoffs
  • 数据驱动:自动化性能分析工具-pprof,依靠数据而非猜测,首先优化最大瓶颈

自动内存管理

动态内存:程序在运行时根据需求动态分配的内存malloc()

自动内存管理(垃圾回收):由程序语言的运行时系统管理动态内存

避免手动内存管理,专注于实现业务逻辑

保证内存使用的正确性安全性: double-free problem, use-after-free problem

相关观念:

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

追踪垃圾回收

对象被回收的条件:指针指向关系不可达的对象

标记根对象

标记:找到可达对象

清理:所有不可达对象

分代GC

每个对象都有年龄,就像人一样,其实就是经历GC的次数。而目的是,对年轻和老年的对象,制定不同的GC策略,降低整体内存管理的开销,不同年龄的对象处于heap的不同区域。因此要根据不同的对象使用不同的策略。

年轻代:存活的对象非常少,可以采用复制,Gc的吞吐率很高

老年代:对象一直在活着,反复复制开销很大,可以采用mark-sweep collection

引用计数

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

image.png 用这个方法,就不需要了解runtime的实现细节了,内存管理的操作被平摊到程序执行过程中去了。但是维护引用计数的开销太大了,而且无法回收环形数据结构,回收内存时会引发暂停。