記一次內存泄漏問題排查
阿新 • • 發佈:2018-06-13
set mage let tac rtb repo int exc adt
通過MonitoSDK的Sample App進行試用時,發現存在部分內存泄漏的情況,leakcanary直接彈出提示如下
可以看到MonitorDBActivity的instance導致泄漏。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_db); ButterKnife.bind(this); } @OnClick(R.id.inputData)public void inputData() { EditText input = (EditText) findViewById(R.id.inputTestData); int num = Integer.valueOf(input.getEditableText().toString()); ErrorReporter reporter = ACRA.getErrorReporter(); CrashReportDataFactory factory = null; try { factory= Reflect.on(reporter).get("crashReportDataFactory"); } catch (ReflectException e) { e.printStackTrace(); } for (int i = 0; i < num; i++) { final ReportBuilder builder = new ReportBuilder(); builder.exception(new Exception(i + ""));final CrashReportData crashReportData = factory.createCrashData(builder); MLog log = null; try { log = new MLog(crashReportData.toJSON().toString()); } catch (JSONReportBuilder.JSONReportException e) { e.printStackTrace(); } MLogStoreMgr.getInstance(this).add(log); } }
可以看到,log相關操作只有MLogStoreMgr.getInstance(this).add(log);這一行代碼,繼續debug,可以看到最後底層執行的是
if(!UploadTask.isRunning()) { TaskExecutor.getInstance().postDelayed(1, new UploadTask() { public void onUploadExcuted() { if(UploadEngine.this.bRunning) { UploadEngine.this.calNextInterval(); if(TaskExecutor.getInstance().hasCallbacks(1)) { TaskExecutor.getInstance().removeCallbacks(1); } if(!UploadTask.isRunning()) { TaskExecutor.getInstance().postDelayed(1, this, UploadEngine.this.mPeriod); } } } public void deleteError() { } }, this.mPeriod); }
沒錯,就是這個postDelayed導致的。這可是在主線程執行的。因此因為這個方法,導致主線程MainActivity的引用無法被釋放,直到消息被looper處理掉。因此,做了如下改造。
記一次內存泄漏問題排查