背景
公司app线上崩溃70%以上为OOM,创建线程时报出。原因有2,
第一,线程创建太多了,超出了系统限制
线程可以通过as cpu中 threads试图进行分析,也可以自己打印出来上报到日志系统,在每次崩溃之后,或者每隔多久收集一次。进行排序计数,找出数量最多,占着茅坑不拉屎的线程名字。
在as中安装JD-IntelliJ is a plug-in for the IntelliJ IDEA platform. It allows you to display all the Java sources during your debugging process, even if you do not have them all. It is based on the famous tools JD-GUI.
他是一个基于著名的jd-gui开发的工具,可以方便的查看jar包,然后可以快速匹配jar包中字符串,很牛逼,不然一个个jar拷出来放到jd-gui查看很痛苦的
发现这个插件并不能达到我们在所有jar包中查找指定字符串的目标。
https://stackoverflow.com/questions/10331025/how-to-search-for-a-string-in-jar-files/10331145 这里面给出了一种方案
首先我们安装 cygwin,然后我发现zipgrep命令找不到,最后在谷歌中搜索zipgrep: command not found才知道zipgrep命令属于unzip这个package,然后重新点击cygwin的set.up.exe文件进行安装,在select pageage中选择full ,搜索unzip,勾选安装,重新打开命令行,命令成功运行
Todo : 这里可以待探索如何在as界面就可以看到线程由哪段代码创建?
Q:遇到cygwin乱码的问题
A:在Cygwin终端上右键-->Options…-->Text-->修改Locale 为 zh_CN,Character Set 为 GBK,问题便得到解决
使用zipgrep指令去寻找哪里创建的 宣告失败
最后通过Google搜索“pool-xx-thread”,找到是
https://stackoverflow.com/questions/47257571/how-to-hook-thread-creation-in-android
大多数正在运行的线程被命名为“ pool-xx-thread-1”,这是由生成的默认名称Executors.DefaultThreadFactory
。似乎某些库代码创建了许多单线程池。
然后发现com.yunji.treabox.zkit.ExecutorUtil这个类用到了源码中的线程池
第二,内存使用不当,堆内存不足
内存使用不当,需要进行内存治理
内存治理的大方向无外乎
1.内存泄漏
后面会开专题
主要利用as profile ,操作可能会泄露的界面,退出该界面,手动多出发几次Gc,然后memory dump出.hprof文件,hprof-conv转译后使用MAT进行分析
再就是比较内存泄漏前后的内存快照,很容易就能找到泄漏点
2.内存抖动
cpu视图上可以看到哪个方法耗时
memery视图可以record ,完了会排出哪些对象的数量大,占内存高,可以分析是哪个类导致
3.bitmap治理