Android Memory/Resource Leak总结
Android的内存/资源泄露,不容易发现,又会引发app甚至是system的一系列问题。
在这里我根据以往碰到的相关问题,总结出了一些检测和修改方法。
*有可能造成memory leak的代码是Framework层的文件,但最终影响了App层的进程;
所以发现app进程出现memory
leak的时候,也要考虑Framework层是否有问题。
*确保一定close资源:try { return; } finally {
resource.close(); } 这样即使try块中有return语句,也能保证finally块中的close被执行到。
*resource
leak的检查需要启动StrictMode。
1.文件IO没有关闭
现象:对app进行重复“进入-退出”的自动化测试,500+次之后出现ANR。
E/StrictMode( 618): A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks. E/StrictMode( 618): java.lang.Throwable: Explicit termination method ‘close‘ not called E/StrictMode( 618): at dalvik.system.CloseGuard.open(CloseGuard.java:184) E/StrictMode( 618): at java.io.FileInputStream.<init>(FileInputStream.java:80) E/StrictMode( 618): at java.io.FileReader.<init>(FileReader.java:42) E/StrictMode( 618): at android.net.http.AndroidHttpClient.fun3(AndroidHttpClient.java:) <- 出错位置 E/StrictMode( 618): at android.net.http.AndroidHttpClient.fun2(AndroidHttpClient.java:) E/StrictMode( 618): at android.net.http.AndroidHttpClient.fun1(AndroidHttpClient.java:) E/StrictMode( 618): at com.android.server.location.GpsXtraDownloader.doDownload(GpsXtraDownloader.java:143) E/StrictMode( 618): at com.android.server.location.GpsXtraDownloader.downloadXtraData(GpsXtraDownloader.java:100) E/StrictMode( 618): at com.android.server.location.GpsLocationProvider$6.run(GpsLocationProvider.java:1023) E/StrictMode( 618): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080) E/StrictMode( 618): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573) E/StrictMode( 618): at java.lang.Thread.run(Thread.java:841)
这种错误不会被容易察觉,但可以避免或在前期找出错误。
小结:
a.不再使用的文件IO要调用close()释放;
b.搜索Log中是否有"release",
"leak", "java.io.Closeable"等关键词;
c.BufferedReader br = new BufferedReader(new
FileReader(file));
close掉BufferedReader也会隐式close掉FileReader;
d.可能有频繁GC,造成屏幕画面卡顿(如Rotation):
12-06 13:44:13.970 9552 9556 E dalvikvm: 9552(com.test.app) stat: (e) 63 937KB / (c) 11 31MB / (a) 4 13MB / (h) 15MB 20MB 4485KB 12-06 13:44:13.970 9552 9556 D dalvikvm: GC_CONCURRENT freed 8183K, 32% free 23967K/34952K, paused 4ms+25ms, total 150ms 12-06 13:44:13.970 9552 9652 D dalvikvm: WAIT_FOR_CONCURRENT_GC blocked 156ms 12-06 13:44:13.970 9552 9654 D dalvikvm: WAIT_FOR_CONCURRENT_GC blocked 155ms 12-06 13:44:13.970 9552 9658 D dalvikvm: WAIT_FOR_CONCURRENT_GC blocked 156ms 12-06 13:44:13.970 9552 9656 D dalvikvm: WAIT_FOR_CONCURRENT_GC blocked 156ms 12-06 13:44:13.975 9552 9660 D dalvikvm: WAIT_FOR_CONCURRENT_GC blocked 157ms 12-06 13:44:13.980 9552 9561 E StrictMode: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks. 12-06 13:44:13.980 9552 9561 E StrictMode: java.lang.Throwable: Explicit termination method ‘close‘ not called 12-06 13:44:13.980 9552 9561 E StrictMode: at dalvik.system.CloseGuard.open(CloseGuard.java:184) 12-06 13:44:13.980 9552 9561 E StrictMode: at java.io.FileInputStream.<init>(FileInputStream.java:80) 12-06 13:44:13.980 9552 9561 E StrictMode: at com.test.app.*(Unknown Source)
2.Cursor没有关闭
现象:自动化测试800+次以后手机reboot
E/StrictMode( 3814): Finalizing a Cursor that has not been deactivated or closed. database = /data/data/com.test.app/databases/..., table = null, query = SELECT * FROM table WHERE package = ‘‘; E/StrictMode( 3814): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here E/StrictMode( 3814): at android.database.sqlite.SQLiteCursor.<init>(SQLiteCursor.java:98) E/StrictMode( 3814): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:50) E/StrictMode( 3814): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1436) E/StrictMode( 3814): at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1375) E/StrictMode( 3814): at com.test.app.*(Unknown Source)
小结:
a.过多cursor会造成Excessive JNI global references,导致system_server的VM
aborting
b.Log关键词:"DatabaseObjectNotClosedException"
相关文章
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。