内存泄漏案例一

如果有其它信息来源,尽量不必要使用crash 工具。原理和之前分析的一致,只是
meminfo 来源不一样。
1. 首先使用kmem -z 查看系统内存的整体情况
发现ANON 占用内存较多为系统中有528MB + 195MB = 733MB 的匿名页 这对于
1GB 的内存的机器来说这本身是不正常的。
NODE: 0 ZONE: 0 ADDR: c0a8c0c0 NAME: "Normal"
SIZE: 194560 MIN/LOW/HIGH: 808/1651/1853
VM_STAT:
NR_FREE_PAGES: 2784
NR_INACTIVE_ANON: 69011
NR_ACTIVE_ANON: 68891
NR_INACTIVE_FILE: 833
NR_ACTIVE_FILE: 800
NR_UNEVICTABLE: 0
NR_MLOCK: 0
NR_ANON_PAGES: 137896 ===>538MB
NR_FILE_MAPPED: 853
NR_FILE_PAGES: 1653
NR_FILE_DIRTY: 2
NR_WRITEBACK: 838
NR_SLAB_RECLAIMABLE: 3399
NR_SLAB_UNRECLAIMABLE: 5314
NR_PAGETABLE: 1784
NR_KERNEL_STACK: 537
NR_UNSTABLE_NFS: 0
NR_BOUNCE: 0
NR_VMSCAN_WRITE: 154187
NR_VMSCAN_IMMEDIATE: 252
NR_WRITEBACK_TEMP: 0
NR_ISOLATED_ANON: 0
NR_ISOLATED_FILE: 0
NR_SHMEM: 1
NR_DIRTIED: 206981
NR_WRITTEN: 359510
NR_ANON_TRANSPARENT_HUGEPAGES: 0
NR_FREE_CMA_PAGES: 0
NODE: 0 ZONE: 1 ADDR: c0a8c3c0 NAME: "HighMem"
SIZE: 67584 MIN/LOW/HIGH: 66/414/498
VM_STAT:
NR_FREE_PAGES: 45
NR_INACTIVE_ANON: 25039
NR_ACTIVE_ANON: 24968
NR_INACTIVE_FILE: 555
NR_ACTIVE_FILE: 529
NR_UNEVICTABLE: 1216
NR_MLOCK: 0
NR_ANON_PAGES: 49999 ===>195MB
NR_FILE_MAPPED: 773
NR_FILE_PAGES: 2322
NR_FILE_DIRTY: 2
NR_WRITEBACK: 550
NR_SLAB_RECLAIMABLE: 0
NR_SLAB_UNRECLAIMABLE: 0
NR_PAGETABLE: 0
NR_KERNEL_STACK: 0
NR_UNSTABLE_NFS: 0
NR_BOUNCE: 0
NR_VMSCAN_WRITE: 877370
NR_VMSCAN_IMMEDIATE: 42
NR_WRITEBACK_TEMP: 0
NR_ISOLATED_ANON: 0
10/13/2015 Copyright 2013 Spreadtrum Communications Inc. Confidential and Proprietary.
18 / 18
NR_ISOLATED_FILE: 0
NR_SHMEM: 8
2. 使用Kmem –i ,或者long total_swap_page+ atomic_long_t nr_swap_pages 直接查看
swap 变量的方式,查看swap 分区情况:
crash> kmem -i
PAGES TOTAL PERCENTAGE
TOTAL MEM 231544 904.5 MB ----
FREE 2829 11.1 MB 1% of TOTAL MEM
USED 228715 893.4 MB 98% of TOTAL MEM
SHARED 3345 13.1 MB 1% of TOTAL MEM
BUFFERS 26 104 KB 0% of TOTAL MEM
CACHED 3949 15.4 MB 1% of TOTAL MEM
SLAB 8713 34 MB 3% of TOTAL MEM
TOTAL HIGH 67584 264 MB 29% of TOTAL MEM
FREE HIGH 45 180 KB 0% of TOTAL HIGH
TOTAL LOW 163960 640.5 MB 70% of TOTAL MEM
FREE LOW 2784 10.9 MB 1% of TOTAL LOW
TOTAL SWAP 153599 600 MB ----
SWAP USED 153599 600 MB 100% of TOTAL SWAP
SWAP FREE 0 0 0% of TOTAL SWAP
或者
crash> long total_swap_pages
total_swap_pages = $1 = 153599 单位为page,转换为KB 要*4。
crash> atomic_long_t nr_swap_pages
struct atomic_long_t {
counter = 0 单位为page,转换为KB 要*4,发现此时swap 空间为0.
}
3. Anon 占用内存太多,且swap 分区使用完,典型的Framework+APP 内存泄漏,执行
Ps 命令找出具体泄漏者, Logd 和system_server 两个进程占用大量内存:
155 1 0 edfe4d80 IN 18.4 261968 193016 logd
252 1 0 ed75b180 IN 18.4 261968 193016 logd.reader
253 1 2 ed75b600 IN 18.4 261968 193016 logd.writer
255 1 1 ed75ba80 IN 18.4 261968 193016 logd
272 1 2 ed765b00 IN 18.4 261968 193016 logd.auditd
388 1 2 ed305b00 IN 18.4 261968 193016 logd.reader.per
4731 1 1 d02bfa80 IN 18.4 261968 193016 logd.reader.per
657 179 3 eccf9b00 IN 47.3 1722300 495904 system_server
660 179 1 ecd42880 IN 47.3 1722300 495904 Heap thread poo
661 179 0 ecd42d00 IN 47.3 1722300 495904 Heap thread poo
663 179 3 ecd43180 IN 47.3 1722300 495904 Heap thread poo
665 179 3 ed354900 IN 47.3 1722300 495904 Signal Catcher
667 179 2 ed357a80 IN 47.3 1722300 495904 JDWP
668 179 3 ed357600 IN 47.3 1722300 495904 ReferenceQueueD
669 179 0 ed356d00 IN 47.3 1722300 495904 FinalizerDaemon
670 179 3 ed356400 IN 47.3 1722300 495904 FinalizerWatchd
671 179 3 ed357180 IN 47.3 1722300 495904 HeapTrimmerDaem
672 179 1 ed356880 IN 47.3 1722300 495904 GCDaemon
689 179 2 ed2dc000 IN 47.3 1722300 495904 Binder_1
690 179 3 eccfa880 IN 47.3 1722300 495904 Binder_2
691 179 2 ed2de400 IN 47.3 1722300 495904 SensorEventAckR
692 179 3 ed2ded00 IN 47.3 1722300 495904 SensorService
693 179 3 eccfad00 IN 47.3 1722300 495904 android.bg
694 179 3 eccfb600 IN 47.3 1722300 495904 ActivityManager
695 179 1 eccfb180 IN 47.3 1722300 495904 FileObserver
696 179 2 ed307a80 IN 47.3 1722300 495904 android.fg
697 179 0 ed306d00 IN 47.3 1722300 495904 android.ui
698 179 0 ed2c9f80 IN 47.3 1722300 495904 android.io
699 179 3 ed2c8000 IN 47.3 1722300 495904 android.display
700 179 0 ed2cad00 IN 47.3 1722300 495904 CpuTracker
701 179 0 ed2cb180 IN 47.3 1722300 495904 PowerManagerSer
702 179 2 ed2c9200 IN 47.3 1722300 495904 system_server
703 179 2 ed2ca880 IN 47.3 1722300 495904 BatteryStats_wa
704 179 0 ed2cba80 IN 47.3 1722300 495904 PackageManager
907 179 2 ecd40900 IN 47.3 1722300 495904 PackageInstalle
10/13/2015 Copyright 2013 Spreadtrum Communications Inc. Confidential and Proprietary.
19 / 19
918 179 1 ecd42400 IN 47.3 1722300 495904 AlarmManager
925 179 1 ecd43a80 IN 47.3 1722300 495904 InputDispatcher
> 926 179 2 ecd41680 RU 47.3 1722300 495904 InputReader
927 179 2 eceaa880 IN 47.3 1722300 495904 MountService
928 179 2 eceaad00 IN 47.3 1722300 495904 VoldConnector
1315 179 3 ecd41b00 IN 47.3 1722300 495904 NetdConnector
1316 179 0 ece5e880 IN 47.3 1722300 495904 NetworkStats
1317 179 2 ece5d680 IN 47.3 1722300 495904 NetworkPolicy
1318 179 2 ece5ed00 IN 47.3 1722300 495904 WifiP2pService
1319 179 0 ece5f180 IN 47.3 1722300 495904 WifiStateMachin
1320 179 2 ece5c000 IN 47.3 1722300 495904 WifiService
1321 179 2 ecd41200 IN 47.3 1722300 495904 ConnectivitySer
1323 179 0 ecd40480 IN 47.3 1722300 495904 NsdService
1324 179 3 ecd43600 IN 47.3 1722300 495904 mDnsConnector
1325 179 2 ecd40d80 IN 47.3 1722300 495904 ranker
1326 179 2 ecd40000 IN 47.3 1722300 495904 AudioService
1327 179 3 ecd41f80 IN 47.3 1722300 495904 Binder_3
1328 179 0 eceab180 IN 47.3 1722300 495904 UEventObserver
1338 179 0 ece5cd80 IN 47.3 1722300 495904 WifiManager
1339 179 3 ece5f600 IN 47.3 1722300 495904 WcnManagerServi
1340 179 3 ece5d200 IN 47.3 1722300 495904 WcndConnector
1341 179 2 ecea9200 IN 47.3 1722300 495904 WifiWatchdogSta
1342 179 2 ecea8d80 IN 47.3 1722300 495904 WifiScanningSer
1343 179 3 ecea8900 IN 47.3 1722300 495904 WifiRttService
1344 179 2 ecea8000 IN 47.3 1722300 495904 backup
4. 查看Logd 和system_server 两个进程的具体内存使用情况:
通过其task_struct 来找到其对应的mm_struct
在mm_struct 中的rss_stat 记录了这个进程所拥有的文件页的数量 匿名页的数量 以及被swap 出去的匿名页的数量
logd:
rss_stat = {
count = {{
counter = 65
}, {
counter = 48121 =====拥有的匿名页187.9MB
}, {
counter = 12538 =====swap 出去的匿名页48.9MB
}}
},
可以看到logd 拥有187.9 + 48.9 = 236.8 MB 的匿名页 这个有点多
system_server:
rss_stat = {
count = {{
counter = 1054
}, {
counter = 121755 ==========拥有匿名页475MB
}, {
counter = 116956 =======swap 出去的匿名页456MB
}}
},
system_server 拥有475 + 456 = 931MB 的匿名页 同时其虚拟地址空间已使用1722300 = 1.6GB 的大小

5. 确认logd 和 system_server 存在内存泄露的风险尤其是system_server

 

 

 

修改后的procrank命令可查看进程rss和swap的使用情况,可排查哪个进程导致。ps命令看不了swap信息。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ThreadLocal是Java中的一个工具类,主要用于保持线程间的数据隔离。然而,不正确地使用ThreadLocal可能导致内存泄漏内存泄漏是指在程序中使用的内存无法被垃圾回收机制回收,导致内存占用不断增加。ThreadLocal的内存泄漏案例如下: 1. 长生命周期的ThreadLocal对象:如果一个ThreadLocal对象的生命周期比应用程序还长,导致ThreadLocal所持有的value对象无法被释放。此时,即使ThreadLocal对象已不再被调用,value对象仍然在ThreadLocalMap中存在,并且无法被垃圾回收,导致内存泄漏。 2. 线程池的ThreadLocal未清理:在使用线程池的环境下,如果某个线程绑定了一个ThreadLocal对象,而未在任务执行结束后手动清除绑定的值,那么该ThreadLocal对象将一直存在于线程池中。如果线程池中的线程数量非常大,将会导致大量ThreadLocal对象未被释放,从而造成内存泄漏。 3. 循环引用:当ThreadLocal对象和其它对象之间存在循环引用关系时,也会导致内存泄漏。因为ThreadLocalMap中的Entry是弱引用,但如果ThreadLocal对象本身被其它对象强引用,就会导致ThreadLocalMap中的Entry无法被清理,从而造成内存泄漏。 为避免ThreadLocal内存泄漏,应注意以下几点: 1. 及时清理ThreadLocal对象:使用完ThreadLocal对象后,应手动调用其remove()方法,确保对应的value对象能够被释放。 2. 避免长生命周期的ThreadLocal对象:尽量将ThreadLocal对象定义为局部变量,而非静态变量或全局变量。 3. 线程池中使用ThreadLocal的安全清理:在使用线程池时,确保在任务执行结束后及时清理线程中绑定的ThreadLocal对象。 4. 避免循环引用:注意ThreadLocal对象与其它对象之间的引用关系,避免产生循环引用。 总而言之,ThreadLocal内存泄漏是由于一些使用不当造成的,合理使用ThreadLocal并进行正确的清理操作,能避免内存泄漏问题的发生。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值