android句柄泄漏
前言
在android開發(fā)過程中缚忧,跑一些單元測(cè)試忙迁,很容易暴露出文件句柄泄漏的問題。前段時(shí)間就有這么一個(gè)bug,最后確定是文件句柄泄漏的問題衡招。下面我記錄下當(dāng)時(shí)一步步如何查找定位句柄泄漏。
正文
首先讓我們看一眼拋錯(cuò)的log日志肪虎。
10-27 00:35:32.141 7437 7437 E AndroidRuntime: FATAL EXCEPTION: main
10-27 00:35:32.141 7437 7437 E AndroidRuntime: Process: com.Android56, PID: 7437
10-27 00:35:32.141 7437 7437 E AndroidRuntime: java.lang.RuntimeException: Could not read input channel file descriptors from parcel.
10-27 00:35:32.141 7437 7437 E AndroidRuntime: at android.view.InputChannel.nativeReadFromParcel(Native Method)
10-27 00:35:32.141 7437 7437 E AndroidRuntime: at android.view.InputChannel.readFromParcel(InputChannel.java:148)
10-27 00:35:32.141 7437 7437 E AndroidRuntime: at android.view.InputChannel$1.createFromParcel(InputChannel.java:39)
這里有一句Could not read input channel file descriptors from parcel豌研,然后我們?cè)谶@句話的上面又發(fā)現(xiàn)一個(gè)有價(jià)值的信息。
Caused by: java.io.IOException: Too many open files
通過網(wǎng)上搜索贬丛,基本判斷這是一個(gè)文件句柄泄漏的問題撩银。
那么我們?cè)撊绾尾檎椅募浔孤┑牡胤侥亍?/p>
首先我們需要做到監(jiān)控文件句柄數(shù),由于android是linux的內(nèi)核豺憔,所以额获,系統(tǒng)為每一個(gè)進(jìn)程都有一個(gè)文件句柄的目錄。
我們先通過ps命令恭应,獲取到我們app的進(jìn)程id抄邀。
然后找到一個(gè)root過的手機(jī),或者使用andorid模擬器昼榛,然后用adb連接到手機(jī)境肾,通過shell命令進(jìn)入到/proc/進(jìn)程id/fd這個(gè)目錄。由于linux關(guān)于系統(tǒng)的管理都是用文件方式,所以這個(gè)文件夾下面就是所有被打開的句柄奥喻。
我們可以在app運(yùn)行的過程中偶宫,不斷的進(jìn)入到這個(gè)目錄中,然后用ls -l 命令列出所有的文件句柄环鲤,這樣就能看到文件句柄有哪些是增長(zhǎng)的纯趋。然后再根據(jù)不同類型的文件句柄,初步定位是什么在泄漏冷离。
在排查的過程中吵冒,為了方便獲取某個(gè)進(jìn)程的句柄數(shù),我寫了一個(gè)簡(jiǎn)單的shell腳本西剥。有需要的同學(xué)可以拿去使用痹栖。
echo '查詢進(jìn)程占用文件句柄數(shù)'
set `adb shell ps |grep com.Android56 |grep -v channel |grep -v Daemon`
pidnum=$2
index=0
while true
do
index=$[index+1]
echo '##################'
echo '第'$index'次查詢'
echo '總句柄'
adb shell ls -l /proc/$pidnum/fd |grep "" -c
echo 'anon句柄'
adb shell ls -l /proc/$pidnum/fd |grep anon -c
echo '##################'
sleep 2
done
總結(jié)
通過艱難的排查過程,終于定位到是播放器打開so動(dòng)態(tài)鏈接庫的時(shí)候瞭空,一個(gè)文件沒有釋放结耀。
具體而言就是,調(diào)用了dlopen匙铡、dlsym图甜,但是沒有調(diào)用dlclose這個(gè)方法。以后在編程的過程中鳖眼,一定得多注意這種涉及資源方面的東西黑毅。有打開必須有關(guān)閉。同時(shí)我建議在測(cè)試的過程中钦讳,可以加入對(duì)文件句柄的監(jiān)控矿瘦,這樣可以更好的發(fā)現(xiàn)問題,避免線上出bug愿卒。