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)
  

 

posted @ 2021-07-06 23:29  皮特99  阅读(453)  评论(0编辑  收藏  举报