kconfig 、 mmap fail 、 android.mk 加debug log 、echo 内存泄漏debug
1.v4l2-core下
kconfig config VIDEO_V4L2 makefile obj-$(CONFIG_VIDEO_V4L2) += videodev.o obj-$(CONFIG_VIDEO_V4L2) += videocommon.o
由此可知 kconfig 里定义的宏,也可以在项目 config 中添加
2.kernel buffer操作函数
videobuf2-vmalloc.h extern const struct vb2_mem_ops vb2_vmalloc_memops; videobuf2-dma-contig.h extern const struct vb2_mem_ops vb2_dma_contig_memops; videobuf2-dma-sg.h extern const struct vb2_mem_ops vb2_dma_sg_memops; videobuf2-vmalloc.c const struct vb2_mem_ops vb2_vmalloc_memops = { videobuf2-dma-sg.c const struct vb2_mem_ops vb2_dma_sg_memops = { videobuf2-dma-contig.c const struct vb2_mem_ops vb2_dma_contig_memops = {
vivi.c q->mem_ops = &vb2_vmalloc_memops; mcam-core.c vq->mem_ops = &vb2_vmalloc_memops; /android/kernel/drivers/media/platform/marvell-ccic/
而高通则是:
msm_vb2.c static struct vb2_mem_ops msm_vb2_get_q_mem_op = { ---- 感觉高通并没有使用上面的定义 vpu_vb2_queue.c static struct vb2_mem_ops vpu_vb2_mem_ops = { msm_vb2.c req->get_buf = msm_vb2_get_buf 对应 kernel msm_buf_mgr.c msm_isp_axi_util.c msm_generic_buf_mgr.c msm_isp_stats_util.c 都有 get_buf , vendor 也有很多 videobuf2-core.h --- 声明 struct vb2_mem_ops { void *(*alloc)(void *alloc_ctx, unsigned long size, gfp_t gfp_flags); void (*put)(void *buf_priv); struct dma_buf *(*get_dmabuf)(void *buf_priv); void *(*get_userptr)(void *alloc_ctx, unsigned long vaddr, unsigned long size, int write); void (*put_userptr)(void *buf_priv); ..... }
3.解析库:
pitter@ubuntu88-PowerEdge-R710:~/work$ addr2line -e libmmcamera2_pproc_modules.so 00001c10 00007ee8 /home/dpi/qb5_8814/workspace/COMBINATION/android/vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/pproc-new/pproc_port.c:1457 /home/dpi/qb5_8814/workspace/COMBINATION/android/vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/pproc-new/pproc_port.c:1696 addr2line -e libmmcamera2_sensor_modules.so 000141e0 0002b5a6 0002c248 0002c9ca 0002c3ea /home/dpi/qb5_8814/workspace/COMBINATION/android/vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors//module/module_sensor.c:2148 /home/dpi/qb5_8814/workspace/COMBINATION/android/vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors//chromatix/module/chromatix_list.c:188 /home/dpi/qb5_8814/workspace/COMBINATION/android/vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors//chromatix/module/chromatix_lru.c:120 /home/dpi/qb5_8814/workspace/COMBINATION/android/vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors//chromatix/module/chromatix_manager.c:116 /home/dpi/qb5_8814/workspace/COMBINATION/android/vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors//chromatix/module/chromatix_lru.c:171
4.由于内存泄漏导致的 mmap fail:
------ MEMORY INFO (/proc/meminfo) ------ MemTotal: 3613080 kB MemFree: 139020 kB Buffers: 135548 kB Cached: 809252 kB SwapCached: 2516 kB
VmallocTotal: 460800 kB VmallocUsed: 170156 kB VmallocChunk: 93212 kB
------ CPU INFO (top -n 1 -d 1 -m 30 -t) ------ User 30%, System 31%, IOW 0%, IRQ 0% User 443 + Nice 0 + Sys 464 + Idle 557 + IOW 0 + IRQ 0 + SIRQ 4 = 1468 PID TID PR CPU% S VSS RSS PCY UID Thread Proc 3208 3208 2 11% R 5472K 1280K fg root procrank procrank 1644 1667 2 7% S 1943320K 209572K fg system Binder_2 system_server ------ VMALLOC INFO (/proc/vmallocinfo) ------ 0x00000000-0x00000000 151552 module_alloc_update_bounds+0xc/0x5c pages=36 vmalloc 0x00000000-0x00000000 36864 module_alloc_update_bounds+0xc/0x5c pages=8 vmalloc 0x00000000-0x00000000 585105408 map_lowmem+0x0/0x24c phys=10000000 lowmem 0x00000000-0x00000000 8192 of_iomap+0x30/0x38 phys=b000000 ioremap 0x00000000-0x00000000 8192 of_iomap+0x30/0x38 phys=b002000 ioremap 0x00000000-0x00000000 8192 ipa_uc_event_handler+0x1ac/0x2b8 phys=7945000 ioremap 0x00000000-0x00000000 8192 of_iomap+0x30/0x38 phys=b121000 ioremap 0x00000000-0x00000000 8192 cpp_load_fw+0x1c/0x2b8 phys=1b00000 ioremap
------ PROCESSES (ps -P --abi) ------ USER PID PPID VSIZE RSS PCY WCHAN PC ABI NAME root 1 0 8264 916 fg SyS_epoll_ 0008511c S 32 /init root 2 0 0 0 fg kthreadd 00000000 S kthreadd root 3 2 0 0 fg smpboot_th 00000000 S ksoftirqd/0 camera 712 1 3096632 39032 fg poll_sched b6bcc05c S 32 /system/bin/mm-qcamera-daemon system 713 1 9196 1220 fg futex_wait b6e446d8 S 32 /system/bin/time_daemon VSS 接近3G camera-daemon 创建3000+ 线程
01-07 00:03:18.700 712 2857 E : Camera[ERROR][MCT ] mct_stream_create_buffers: 3609: mct_stream_create_buffers: Mapping failed with error Out of memory 01-07 00:03:18.700 712 2857 E : Camera[ERROR][MCT ] mct_stream_create_buffers: 3656: mct_stream_create_buffers: for stream type: 1 01-07 00:03:18.700 712 2857 E : Camera[ERROR][MCT ] mct_pipeline_map_buf: 755: mct_pipeline_map_buf: Mapping failed for buf type 3
全局变量引起的内存假泄漏:
#include<iostream> #include<ctime> using namespace std; int main() { time_t tme; struct tm *stm; for(int i=0;i<50;i++) { time(&tme); stm=localtime(&tme); ---------- 虽然运行一次内存增加,但运行多次内存包保持不变,因此不是内存泄漏 cout<<(int)stm<<endl; } system("pause"); return 0; }
执行以上代码,发现程序每次运行stm都指向同一个地址,不知道这是为什么。是不是指向了全局变量区?单线程库基本上是静态的, 多线程的一般都TLS的, 不同的线程指向不同的内存...
http://blog.csdn.net/hudashi/article/details/7051312
Android has a tool called procrank (/system/xbin/procrank), which lists out the memory usage of Linux processes in order from highest to lowest usage.
The sizes reported per process are VSS, RSS, PSS, and USS.
可以使用adb shell dumpsys meminfo -a <process id>/<process name>来查看一个进程的memory
下面可以看到 USS 有在增加: (查看所有进程的内存使用情况,可以使用命令procrank、dumpsys meminfo查看)
old cac lib: #A6 887 198612K 37640K 29676K 28836K 0K /system/bin/mm-qcamera-daemon -- after reboot 14608 1713188K 90808K 42757K 38120K 1364K com.sec.android.app.camera 887 454068K 44324K 36350K 35520K 3644K /system/bin/mm-qcamera-daemon -- after take 939 pictures: 887 204788K 33904K 25940K 25100K 3644K /system/bin/mm-qcamera-daemon -- close cam new cac lib: #A2 853 194776K 37372K 29414K 28576K 0K /system/bin/mm-qcamera-daemon -- after reboot 14219 1789956K 107356K 57197K 48608K 2944K com.sec.android.app.camera -- after take 857 pictures: 853 447152K 38420K 30439K 29608K 10796K /system/bin/mm-qcamera-daemon 853 197872K 26448K 18475K 17636K 10796K /system/bin/mm-qcamera-daemon -- close cam
http://www.xuebuyuan.com/706122.html --- 参考 http://www.it165.net/pro/html/201406/16404.html
一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS
VSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)是单个进程全部可访问的地址空间
RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存)是单个进程实际占用的内存大小,对于单个共享库, 尽管无论多少个进程使用,实际该共享库只会被装入内存一次。
PSS - Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
USS - Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)USS 是一个非常非常有用的数字, 因为它揭示了运行一个特定进程的真实的内存增量大小。如果进程被终止, USS 就是实际被返还给系统的内存大小。
USS 是针对某个进程开始有可疑内存泄露的情况,进行检测的最佳数字。怀疑某个程序有内存泄露可以查看这个值是否一直有增加
得分清“可以寻址”和“实际使用”的区别。其实我们讲的每个进程都有4G虚拟地址空间,讲的都是“可以寻址”4G,意思是虚拟地址的0-3G对于一个进程的用户态和内核态来说是可以访问的,而3-4G是只有进程的内核态可以访问的。并不是说这个进程会用满这些空间。其次,所谓“独立拥有的虚拟地址”是指对于每一个进程,你可以访问自己的0-4G的虚拟地址。虚拟地址是“虚拟”的,需要转化为“真实”的物理地址。好比你有你的地址簿,我有我的地址簿。你和我的地址簿都有1、2、3、4页,但是每页里面的实际内容是不一样的,我的地址簿第1页写着3,你的地址簿第1页写着4,对你我自己来说都是用第1页(虚拟),实际上用的分别是第3、4页(物理),不冲突。
地址有三种,逻辑地址、线性地址、物理地址,物理地址通过分段机制变成线性地址,线性地址通过分页机制变成逻辑地址。
每个进程有各自的私有用户空间(0~3G),这个空间对系统中的其他进程是不可见的。最高的1GB字节虚拟内核空间则为所有进程以及内核所共享
64位的linux系统下,进程的地址空间是多大?(32位是4g,1g内核,3g用户)
4位的linux采用4级页表,支持的最大物理内存为64T。对于虚拟地址空间的划分,将0x0000,0000,0000,0000 – 0x0000,7fff,ffff,f000这128T地址用于用户空间;而0xffff,8000,0000,0000以上的128T为系统空间地址。
用echo输出空行至少有十种方法:
echo= echo, echo; echo+ echo/ echo[ echo] echo: echo. echo\ pause
这十种方法可以分为三组,每组的效率依次递减。可悲的是,那些被奉为经典的教程给出的却是效率最低那组中的echo.
Total PSS by OOM adjustment: Total ( PSS SwapPss ) kB 1698264 ( 828913 869351 ) kB: Native Total ( PSS SwapPss ) kB 1542131 ( 736827 805304 ) kB: rild (pid 541) 39207 ( 32911 6296 ) kB: mediaserver (pid 543) 50207 ( 31247 18960 ) kB: mm-qcamera-daemon (pid 712)
查看线程:
ps -t 就可以看到所有线程
搜fg do_sigtime,就可以看到,这里有两千多的线程,都是属于camera的
------ PROCESSES AND THREADS (ps -t -p -P -x -c) ------ ------ 查看所有线程 USER PID PPID VSIZE RSS CPU PRIO NICE RTPRI SCHED PCY WCHAN PC NAME camera 712 1 3096632 39032 0 20 0 0 0 fg poll_sched b6bcc05c S /system/bin/mm-qcamera-daemon (u:2846714, s:898530) camera 1550 712 3096632 39032 7 20 0 0 0 fg futex_wait b6ba26d8 S mm-qcamera-daem (u:0, s:0)---- 可以查看进程 712 创建的线程 camera 1551 712 3096632 39032 6 20 0 0 0 fg futex_wait b6ba26d8 S mm-qcamera-daem (u:0, s:1) camera 1552 712 3096632 39032 6 20 0 0 0 fg sync_fence b6bcbf98 S mm-qcamera-daem (u:0, s:6)
其实我觉得应该从这行log发掘信息,都是POSIX timer,都是(u:0, s:0),这个表示这个线程在用户态和核心态都没有占用时间 创建那么多线程,一点代码都没跑,有点不正常
VSS是代码上申请的内存,但不是实际占用的,PSS是实际占用的 相当于当你写东西进去,才会实际占用
------ PROCESSES (ps -P --abi) ------ USER PID PPID VSIZE RSS PCY WCHAN PC ABI NAME camera 717 1 2890236 37648 fg poll_sched b6c4e05c S 32 /system/bin/mm-qcamera-daemon --- VSS 差不多3G system 718 1 9196 1212 fg futex_wait b6f0b6d8 S 32 /system/bin/time_daemon
------ PROCRANK (procrank) ------ PID Vss Rss Pss Uss Swap cmdline 3702 1648000K 74612K 29586K 26348K 13640K com.sec.android.app.launcher 717 2890232K 37560K 29522K 28156K 20632K /system/bin/mm-qcamera-daemon 4854 1066852K 43844K 11668K 10852K 6684K android.process.media
内存情况:
------ MEMORY INFO (/proc/meminfo) ------ MemTotal: 3613080 kB MemFree: 97092 kB Buffers: 140868 kB Cached: 739504 kB SwapCached: 3436 kB
%p 依赖于实现, 可以用 %d, %x, %u 试试 --- 打印指针 ,经常会用到gettid(),来获取线程号,判断问题出在哪个线程里面
#include <sys/types.h> #include <linux/unistd.h> #include <errno.h> 使用上面的头文件可能会出现诸如这样的error: undefined reference to `gettid' #include <sys/syscall.h> /*此头必须带上*/ pid_t gettid() { return syscall(SYS_gettid); /*这才是内涵*/ }
我的项目中thread ID都是顺序下来的,进程也即主线程ID为45,然后分别创建了4个子线程,其按照创建顺序,分配的ID分别为46,47,48,49。有进程PID都能在/proc下看到,ls /proc 的话,所有数字都代表一个进程,下一步
# ls /proc/45/task/
45 46 47 48 49 /* ok 该进程下的所有thread ID都展现在我们眼前了*/ ------------- 查看进程所创建的线程
怎么查看内存泄漏:
@echo off echo start the job...... cd D:\android-sdk-windows\sdk\tools adb root adb wait-for-device adb remount adb shell setprop libc.debug.malloc 40 adb shell setprop libc.debug.malloc.program mm-qcamera-daemon adb shell setprop libc.debug.malloc.minalloclim 100 adb shell setprop libc.debug.malloc.maxprocsize 314572800 adb shell stop adb shell start adb logcat -v threadtime >xxx.log adb shell ps | find "mm-qcamera-daemon" adb shell kill -9 <pid of mm-qcamera-daemon> adb shell ps | find "mm-qcamera-daemon" adb shell kill -28 <pid of mm-qcamera-daemon> {do reproduce} adb shell kill -28 <pid of mm-qcamera-daemon> save the log ping 127.0.0.1 -n 1 > nul echo stop the job! echo. & pause
01-01 08:20:06.409 17907 17907 E libc : obj 0x9e494c00, size 4096 01-01 08:20:06.409 17907 17907 E libc : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 01-01 08:20:06.409 17907 17907 E libc : #00 pc 00007692 /system/lib/libc_malloc_debug_leak.so (chk_malloc+77) ... 01-01 08:20:06.409 17907 17907 E libc : #09 pc b0f7189a /system/vendor/lib/libllvm-qcom.so (cl_compiler_compile_source+141) 01-01 08:20:06.409 17907 17907 E libc : #10 pc b2def834 /system/vendor/lib/libCB.so (cl_compiler_wrapper_compile_source+95) 01-01 08:20:06.409 17907 17907 E libc : #11 pc b2dfffd4 /system/vendor/lib/libCB.so 01-01 08:20:06.409 17907 17907 E libc : #12 pc b2e00e18 /system/vendor/lib/libCB.so (cl_program_build_immediate+75) 01-01 08:20:06.409 17907 17907 E libc : #13 pc b2e01bf4 /system/vendor/lib/libCB.so (cb_build_program+827) 01-01 08:20:06.409 17907 17907 E libc : #14 pc b2fd72d6 /system/vendor/lib/libOpenCL.so (qCLDrvAPI_clBuildProgram+41) 01-01 08:20:06.409 17907 17907 E libc : #15 pc b2f2442e /system/vendor/lib/libmmcamera_cac3_lib.so (rnrgpu_build_program+81)
这样就表示有内存泄漏: (在这里打出来,就是Rss了)
01-01 08:20:06.579 17907 17907 E libc : Total Pending allocations after last snapshot: 1941499 ---- 表示没有释放,单位是字节 -- 1.85M RSS 01-01 08:20:06.579 17907 17907 E libc : *** +++ *** +++ *** +++ *** +++ *** +++ *** +++ *** +++ *** +++ 01-01 08:20:06.579 17907 17907 E libc : Completed dumping allocations of the process /system/bin/mm-qcamera-daemon 虚拟地址空间,接近3GB,占用的是VSS,那个用完了,也会有问题
在Android.mk 打印 log:
在 Android.mk 文件添加log : ifeq ($(call is-board-platform,msm8952),true) ifeq ($(strip $(TARGET_BOARD_SUFFIX)),_32) -include $(LOCAL_PATH)/target/product/msm8952_32/Android.mk + $(warning "pitter the value of LOCAL PATH is $(PREBUILT_DIR_PATH) 32") endif endif ifeq ($(call is-board-platform,msm8952),true) ifeq ($(strip $(TARGET_BOARD_SUFFIX)),_64) -include $(LOCAL_PATH)/target/product/msm8952_64/Android.mk + $(warning "pitter the value of LOCAL PATH is $(PREBUILT_DIR_PATH) 64") endif endif 从编译的log中打印有: vendor/qcom/proprietary/prebuilt_HY11/Android.mk:7: "pitter the value of LOCAL PATH is vendor/qcom/proprietary/prebuilt_HY11 32"
参考: http://bbs.csdn.net/topics/390255566 采用新线程派驻的通知方式 evp.sigev_notify = SIGEV_THREAD; //线程通知的方式,派驻新线程 evp.sigev_notify_function = timer_thread; //线程函数地址 使用se.sigev_notify = SIGEV_SIGNAL; 问题解决 se.sigev_notify = SIGEV_THREAD; 这个模式应该是我使用不当吧,应该是每个周期都会单独启动线程,但是总有一个不被释放。 这是函数指针 typedef void(*pFun)(sigval_t); SetTimer(pfun,tid1,13,1); 如何释放?不可能释放的,原因可能是这样的: se.sigev_notify = SIGEV_THREAD; se.sigev_notify_function ……
---------------------------------------------------------------------------------------------------------------- 如果是 SIGEV_THREAD, 有 7 次打印: (timer_create(time_id)) 每次都会创建新的线程,没有释放导致 VSS 泄漏 camera 2526 852 376888 45160 5 20 0 0 0 fg do_sigtime b6c04140 S POSIX timer 0 (u:0, s:0) camera 2553 852 376888 45160 4 20 0 0 0 fg do_sigtime b6c04140 S POSIX timer 1 (u:0, s:0) camera 2645 852 376888 45160 4 20 0 0 0 fg do_sigtime b6c04140 S POSIX timer 2 (u:0, s:0) camera 3047 852 376888 45160 0 20 0 0 0 fg do_sigtime b6c04140 S POSIX timer 3 (u:0, s:0) camera 3309 852 376888 45172 4 20 0 0 0 fg do_sigtime b6c04140 S POSIX timer 4 (u:0, s:0) camera 6974 852 376888 45172 5 20 0 0 0 fg do_sigtime b6c04140 S POSIX timer 5 (u:0, s:0) camera 8340 852 376888 45180 3 20 0 0 0 fg do_sigtime b6c04140 S POSIX timer 6 (u:0, s:0) root@c5pltechn:/proc/858/task # ls ----- 待机,共有 17 个进程 2|root@c5pltechn:/proc/858/task # ls ----- 共有 39 个线程 ---------------------------------------------------------------------------------------------------------------- 如果换成 SIGEV_SIGNAL ,则只打印下面的log一次: (并且在proc/pid_mm-qcamera-daemon/task 下查看进程创建线程也是相对少 6 ) camera 2533 852 372488 45216 4 20 0 0 0 fg do_sigtime b6bfb140 S POSIX timer 0 (u:0, s:0) 将 timer_create 屏蔽或者把 SIGEV_THREAD 换成 SIGEV_SIGNAL 都只打印这个 log,且进程数也减少(这个问题主要是关闭 camera没有调用 timer_delete(time_id) 引起的) root@c5pltechn:/proc/852/task # ls ----- 待机,共有 12 个进程 root@c5pltechn:/proc/852/task # ls ----- 共有 33 个线程 ,打开camera的线程: ----------------------------------------------------------------------------------------------------------------
linux下定时器的使用--timer_create等系列 http://blog.sina.com.cn/s/blog_6abf2c040101fc20.html
最强大的定时器接口来自POSIX时钟系列,其创建、初始化以及删除一个定时器的行动被分为三个不同的函数:timer_create()(创建定时器)、timer_settime()(初始化定时器)以及timer_delete(销毁它)。
int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
进程可以通过调用timer_create()创建特定的定时器,定时器是每个进程自己的,不是在fork时继承的。timer_create的参数clock_id说明定时器是基于哪个时钟的,
*timerid装载的是被创建的定时器的ID。timer_create函数创建了定时器,并将他的ID放入timerid指向的位置中。参数evp指定了定时器到期要产生的异步通知。
如果evp为NULL,那么定时器到期会产生默认的信号,对CLOCK_REALTIMER来说,默认信号就是SIGALRM。对那些定时器到期时要产生除默认信号之外的其它信号的定
时器来说,程序必须将evp->sigev_signo设置为期望的信号码。struct sigevent 结构中的成员evp->sigev_notify说明了定时器到期时应该采取的行动。通常,这个成
员的值为SIGEV_SIGNAL,这个值说明在定时器到期时,会产生一个信号。程序可以将成员evp->sigev_notify设为SIGEV_NONE来防止定时器到期时产生信号。
如果几个定时器产生了同一个信号,处理程序可以用evp->sigev_value来区分是哪个定时器产生了信号。要实现这种功能,程序必须在为信号安装处理程序时,使
用struct sigaction的成员sa_flags中的标志符SA_SIGINFO。
clock_id的取值为以下:
CLOCK_REALTIME :Systemwide realtime clock. CLOCK_MONOTONIC:Represents monotonic time. Cannot be set. CLOCK_PROCESS_CPUTIME_ID :High resolution per-process timer. CLOCK_THREAD_CPUTIME_ID :Thread-specific timer. CLOCK_REALTIME_HR :High resolution version of CLOCK_REALTIME. CLOCK_MONOTONIC_HR :High resolution version of CLOCK_MONOTONIC. int timer_settime(timer_t timerid,int flags,const struct itimerspec *value,struct itimerspec *ovalue); struct itimerspec { struct timespec it_interval; //定时器周期值 struct timespec it_value; //定时器到期值 };
timer_settime负责启动或停止timer_create创建的定时器。参数flag说明定时器使用的是相对时间还是绝对时间。相对时间与POSIX:XSI定时器使用的策略类似,而绝对时间
的精确度更高。参数vaule指向的值来设置timerid指定的定时器。如果ovalue不为NULL,timer_settime就将定时器以前的值放在ovalue指定的位置上。如果定时器正在
运行,那么*ovalue的成员it_value非零,并包含了定时器到期之前剩余的时间。
TIMER_ABSTIME表示绝对时间;如果flag没有设定为TIMER_ABSTIME,则定时器从调用开始在it_value内超时;如果设定为TIMER_ABSTIME,该函数表现为时间直到下一次超时被设
定为it_value指定的绝对时间和与timerid相联的时钟值的差值。定时器的再装由value的it_interval成员值来设定。
int timer_gettime(timer_t timerid,struct itimerspec *value); 获得一个活动定时器的剩余时间。
pthread_create主线程与创建的新线程之间退出关系 http://blog.csdn.net/xiajun07061225/article/details/8976850
timer_create 出现内存泄漏 http://bbs.csdn.net/topics/390255566
这是函数指针
typedef void(*pFun)(sigval_t);
SetTimer(pfun,tid1,13,1);
如何释放?
不可能释放的,原因可能是这样的:
se.sigev_notify = SIGEV_THREAD;
se.sigev_notify_function = pfun;
会让系统启动一个线程,当定时器时间到了之后,就会在这个线程里调用pfun,而这个线程启动之后是不会停止的。
要不你改为
se.sigev_notify = SIGEV_NONE;
或者
se.sigev_notify = SIGEV_SIGNAL;
试试。
使用se.sigev_notify = SIGEV_SIGNAL; 问题解决 参考: http://bbs.csdn.net/topics/390255566
se.sigev_notify = SIGEV_THREAD; 这个模式应该是我使用不当吧,应该是每个周期都会单独启动线程,但是总有一个不被释放。
enable mct timer patch >adb shell procrank |find "qcamera" PID Vss Rss Pss Uss cmdline 701 122168K 34728K 26802K 25952K /system/bin/mm-qcamera-daemon ---- after reboot 713 128312K 35268K 27329K 26488K /system/bin/mm-qcamera-daemon ---- open 10 times 713 128828K 35204K 27265K 26424K /system/bin/mm-qcamera-daemon ---- open 30 times 713 128828K 35280K 27341K 26500K /system/bin/mm-qcamera-daemon ---- open 50 times 713 128836K 35484K 27546K 26704K /system/bin/mm-qcamera-daemon ---- open 100 times 713 128840K 35444K 27506K 26664K /system/bin/mm-qcamera-daemon ---- open 150 times 713 129100K 35588K 27643K 26808K /system/bin/mm-qcamera-daemon ---- open 200 times 713 129108K 35576K 27640K 26796K /system/bin/mm-qcamera-daemon ---- open 250 times 713 129112K 35680K 27744K 26900K /system/bin/mm-qcamera-daemon ---- open 300 times 713 129116K 35648K 27712K 26868K /system/bin/mm-qcamera-daemon ---- open 350 times 713 129124K 35684K 27751K 26904K /system/bin/mm-qcamera-daemon ---- open 400 times 713 129132K 35760K 27827K 26980K /system/bin/mm-qcamera-daemon ---- open 450 times 713 129392K 35712K 27779K 26932K /system/bin/mm-qcamera-daemon ---- open 500 times --- 126.359375 MB
>adb shell procrank |find "qcamera" PID Vss Rss Pss Uss cmdline 706 127320K 34064K 26152K 25300K /system/bin/mm-qcamera-daemon 706 184556K 35420K 27481K 26640K /system/bin/mm-qcamera-daemon ---- open 50 times 706 246484K 35724K 27785K 26944K /system/bin/mm-qcamera-daemon ---- open 100 times 706 300408K 36200K 28260K 27420K /system/bin/mm-qcamera-daemon ---- open 150 times 706 352012K 36240K 28301K 27460K /system/bin/mm-qcamera-daemon ---- open 200 times 706 404652K 36512K 28573K 27732K /system/bin/mm-qcamera-daemon ---- open 250 times 706 457288K 36676K 28745K 27896K /system/bin/mm-qcamera-daemon ---- open 300 times 706 511988K 36928K 28993K 28148K /system/bin/mm-qcamera-daemon ---- open 350 times 706 563592K 37192K 29258K 28412K /system/bin/mm-qcamera-daemon ---- open 400 times 706 615200K 37408K 29474K 28628K /system/bin/mm-qcamera-daemon ---- open 450 times 706 666804K 37364K 29430K 28584K /system/bin/mm-qcamera-daemon ---- open 500 times --- 651.17578125 MB (测试500 次大概增加 500MB 多点平均每次增加1MB 多点,RSS增加 3.22265625 MB)