性能优化以及自动内存管理
这是我参与【第五届青训营】伴学笔记创作活动的第四天
性能优化,优化哪里?
一个产品的性能优化非常重要,好的产品才能够被用户所接受。倘若产品的性能优化非常差劲,页面跳转卡顿,那么它必然是市场的淘汰品。So,性能优化,优化在哪个方面呢?
- 业务层优化:针对特定场景,具体问题,具体分析,容易获得较大性能收益
- 语言运行时优化:解决更通用的性能问题,会考虑到更多场景,Tradeoffs
- 数据驱动:自动化性能分析工具-pprof,依靠数据而非猜测,首先优化最大瓶颈
自动内存管理
动态内存:程序在运行时根据需求动态分配的内存malloc()
自动内存管理(垃圾回收):由程序语言的运行时系统管理动态内存
避免手动内存管理,专注于实现业务逻辑
保证内存使用的正确性和安全性: double-free problem, use-after-free problem
相关观念:
- Mutator:业务线程,分配新对象,修改对象指向关系
- Collector: GC线程,找到存活对象,回收死亡对象的内存空间Serial
- GC:只有一个collector
- Parallel GC:支持多个collectors同时回收的GC算法
- Concurrent GC: mutator(s)和collector(s)可以同时执行
追踪垃圾回收
对象被回收的条件:指针指向关系不可达的对象
标记根对象
标记:找到可达对象
清理:所有不可达对象
分代GC
每个对象都有年龄,就像人一样,其实就是经历GC的次数。而目的是,对年轻和老年的对象,制定不同的GC策略,降低整体内存管理的开销,不同年龄的对象处于heap的不同区域。因此要根据不同的对象使用不同的策略。
年轻代:存活的对象非常少,可以采用复制,Gc的吞吐率很高
老年代:对象一直在活着,反复复制开销很大,可以采用mark-sweep collection
引用计数
每个对象都有一个与之关联的引用数目,对象存活的条件是当且仅当引用数大于0
用这个方法,就不需要了解runtime的实现细节了,内存管理的操作被平摊到程序执行过程中去了。但是维护引用计数的开销太大了,而且无法回收环形数据结构,回收内存时会引发暂停。