鸽了好久, 如今补上缓存
上篇提到, 作好方法堆栈的收集后, 项目工程运行不到两分钟, 出先卡顿, 直至完全卡死.markdown
经过Android Studio Profile调查得知, 正是我统计耗时的MethodNode堆栈撑爆了内存.app
为了监控方法耗时, 可是居然搞出了内存问题, 有些搞头..spa
由于每一个方法都被插桩, 因此每一个方法的先后调用关系都作成MethodNode被存到了堆栈中,设计
因此随着使用时间的增加, 全部方法关系都存进了堆栈中, 不被清理, 就撑爆了内存.code
这个问题其实是个OOM问题. OOM从技术角度看, 是由于改释放的内存不被释放.orm
可是要解决OOM问题, 却须要从具体业务入手, 由于只有经过业务关系梳理, 才知道那些内存应该释放.对象
针对此次的问题, 就是要减小方法关系的存储.内存
由于MethodNode中保存了父节点和子节点信息. 因此当获得一个新MethodNode时,开发
获取它的父节点信息, 再从现有的堆栈中, 找到对应的父节点,
查看该父节点中的全部子节点是否已经包含那个新MethodNode的信息.
若是包含, 说明重复, 则丢弃这个新MethodNode. 若是不包含, 就把新MethodNode加入堆栈里父节点的子节点列表里,
若是没有找到父节点, 则这个新MethodNode直接当作root级别父节点, 存入堆栈
聊这个, 我可就不困了.
特别为这个设计里一个存取交换池.
简单的说, 设计了两个缓存池, 某个时间段内, 一个池只取, 另外一个池只存.
当"只取"的池子空了, 就切换成"只存"状态. 同时, 以前"只存"的池子同步切换为"只取"
这样两个池子, 交替使用
若是两个坑都没有砖, 我就去找砖厂要砖. 回收的砖一样按照轮换扔到当前应该回收转的坑里.
至关于作到存取隔离, 也就没有了存取冲突. 同时有复用机制. 内存的数量不会激增.
过程大体以下:
按照设计, 开发完毕实测.
缓存池初期不断增大, 2w个以后逐渐稳定.再也不增加.
知足了整个app的循环复用. 内存问题解决.