优化前后内存占用的对比
在上一篇 【CVM】【2018.3.16】CVM 的内存占用优化(一) 中,对 CVM 进行了两次优化,这篇将继续进行。
优化前 | 优化(一)后 | 优化(二)后 |
---|---|---|
80.9 MB | 23.2 MB | 9.4 MB |
本文主要是对 parser 的优化。
优化1 : 面向对象的 Instruction 基类添加 virtual 析构
单纯分析 parser ,让 ParseInfo 结构体析构。将相应的组件进行析构。
其中,using InstList = std::vector<Instruction*>>;
在析构 FunctionInfo 时,将 InstList 所有指针删除。
构造前 | 析构前 | 析构后 |
---|---|---|
0.3 MB | 7.1 MB | 4.4 MB |
发现, ParseInfo 并没有完全析构。
根据 VS 2017 的调试工具,发现析构后有许多 Inst 相关的内存没有被释放。 随后发现, Instruction 基类并没有 virtual 析构函数。
加上后,测得:
构造前 | 析构前 | 析构后 |
---|---|---|
0.4 MB | 7.8 MB | 0.6 MB |
可以发现,大部分的 parser 析构成功。
优化2 : 重构 parser
- 将 FunctionInfo 这种公用部分提取出来,直接共享使用(std::shared_ptr)
- 使用 index (size_t) 代替直接使用函数名 (std::string)
FunctionInfo 从 parser 开始,直到 runtime 都在使用。频繁地转换不仅会增加内存占用率(没有及时释放),还会降低效率。
因为 FunctionInfo 生成后是不改变的,在生成过程中会使用 std::vector 这种可变数组,生成后使用一段内存(PriLib::lightlist),遂增加 FunctionInfoCreater ,在生成两个 FunctionInfo 之间会清空状态,这样可以减小内存占用。
Time | 备注 | 占用内存 |
---|---|---|
第一次 pause | parser | 7.7 MB |
第二次 pause | parser + compiler | 15.1 MB |
第三次 pause | parser + compiler + runtime | 16.3 MB |
优化3 : 提前析构 parser
优化1 使得析构 parser 可以获得减少大量内存占用,优化2 重构 parser 后,提前析构 parser 。
结果如下:
Time | 备注 | 占用内存 |
---|---|---|
第一次 pause | parser | 7.8 MB |
第二次 pause | compiler | 8.2 MB |
第三次 pause | compiler + runtime | 9.4 MB |