手机浏览器网站开发工具阜康市建设银行网站
手机浏览器网站开发工具,阜康市建设银行网站,怎样做网站代理,VIP视频网站有得做吗7.5 堆内存管理与信息统计
堆内存是指程序运行时用于动态内存分配的一块内存区域。堆空间不足会带来一系列严重危害#xff1a;
内存分配失败#xff1a;当系统尝试动态分配内存#xff08;如为进程、线程、数据结构分配内存#xff09;时#xff0c;若堆空间不足#xf…7.5 堆内存管理与信息统计堆内存是指程序运行时用于动态内存分配的一块内存区域。堆空间不足会带来一系列严重危害内存分配失败当系统尝试动态分配内存如为进程、线程、数据结构分配内存时若堆空间不足将返回 NULL导致程序逻辑中断或崩溃。系统稳定性下降在操作系统中堆通常用于管理关键资源如进程控制块、文件描述符、网络连接等。若堆空间不足可能导致系统无法创建新进程或处理请求影响系统稳定性。性能下降与资源争用频繁的内存分配与释放可能引发内存碎片降低内存利用率同时增加内存搜索成本影响系统性能。Cobalt 实时内核提供了堆内存管理功能包括堆内存初始化、分配、释放、Debug等定义在kernel/cobalt/heap.c中。在内核态可以通过内核配置选项CONFIG_XENO_OPT_DEBUG_MEMORY来打开默认关闭。它可以用于验证页面的类型是否允许操作帮助开发时发现内存错误如重复释放。注意开启 debug 功能会增加系统开销因此不建议在生产环境中使用。在 QEMU ARM64 虚拟机中开启此选项可能导致启动很慢。在用户态为了便于在用户态观测 Cobalt 实时内核的堆内存使用情况Cobalt 实时内核提供了/proc/xenomai/heap用于显示Cobalt 实时内核在内核空间的堆内存的使用情况。cat /proc/xenomai/heap触发了kernel/cobalt/heap.c中的 vfile_show 函数输出了各个堆内存的名称NAME总大小TOTAL剩余大小FREE。TOTAL FREE NAME 4194304 4183040 system heap 16384 16384 debug log 262144 261952 shared heap 262144 262112 private heap[324]从上述输出可以看到当前系统中共有 4 个堆内存system heap、private heap、shared heap和debug log。这 4 个堆内存的大小都可以在内核配置时进行配置[*] Xenomai/cobalt --- Sizes and static limits --- (4096) Size of system heap (Kb) (256) Size of private heap (Kb) (256) Size of shared heap (Kb) (16) Trace log size特别注意system heap、private heap、shared heap还通过 RTDM 生成了设备文件。具体的用处在下面的章节中介绍。/dev/rtdm/ |-- memdev-private |-- memdev-shared |-- memdev-sys7.5.1 system heapsystem heap是 Cobalt 实时内核在内核空间用于提供内存分配的主堆大小为CONFIG_XENO_OPT_SYS_HEAPSZ默认值为 4MB。在 Cobalt 实时内核中系统堆的分配和释放都是通过xnmalloc和xnfree两个宏来完成的。这两个宏的入参就是system heap对应的全局变量cobalt_heap。extern struct xnheap cobalt_heap; #define xnmalloc(size) xnheap_alloc(cobalt_heap, size) #define xnfree(ptr) xnheap_free(cobalt_heap, ptr)system heap的初始化如下其本质上是在 Linux 内核中在实时内核中提前申请一大块内存然后由 Cobalt 实时内核自己管理。在 Cobalt 实时内核内核态调用xnmalloc分配内存可以避免从 Linux 内核申请内存的开销与延迟保证实时性。static __init int sys_init(void) { void *heapaddr; int ret; if (sysheap_size_arg 0) sysheap_size_arg CONFIG_XENO_OPT_SYS_HEAPSZ; heapaddr xnheap_vmalloc(sysheap_size_arg * 1024); if (heapaddr NULL || xnheap_init(cobalt_heap, heapaddr, sysheap_size_arg * 1024)) { return -ENOMEM; } xnheap_set_name(cobalt_heap, system heap);注意在用户态的POSIX skin中调用malloc分配内存实际上最终走的是 glibc 的malloc通过 Linuxbrk或mmap系统调用分配内存而不是从 system heap 分配内存。对于非 POSIX skin在用户态定义了xnmalloc。调用后根据是否开启--enable-pshared选项会在-lcopperplate库为其初始化的私有堆内存或共享堆内存申请内存空间。另外Alchemy skin 提供了一个额外的 heap 服务其rt_heap_create预先申请的空间根据是否开启--enable-pshared选项而不同如果没有打开enable-psahred则调用 heapmem.c 中的rt_heap_create - heapobj_init - __heapobj_init_private通过 linux malloc 分配内存。如果打开了enable-pshared则调用 heap-pshared.c 中的rt_heap_create - heapobj_init- sheapmem_alloc(main_heap.heap, len);从共享堆内存中分配内存。7.5.2 private heapprivate heap是 Cobalt 实时内核在内核空间专用于存放 IPC 通信对象的状态大小为CONFIG_XENO_OPT_PRIVATE_HEAPSZ默认值为 256KB。每个进程都由自己的 IPC 通信对象所以需要为每个进程单独申请一个私有堆private heap且加上 PID 后缀以便于区分例如private heap[324]。私有堆private heap的创建时机是在 Cobalt 实时内核的内核空间。实时进程初始化时需要中调用sc_coablt_bind实时系统调用进入内核态最终调用cobalt_umm_init创建private heap。private heap创建之后由 struct cobalt_process 结构体的sys_ppd-umm成员变量管理。cobalt_init - cobalt_init_1 - cobalt_init_2 - low_init - XENOMAI_SYSBIND 调用sc_coablt_bind系统调用进入内核态创建cobalt_process - cobalt_process_attach - attach_process - cobalt_umm_init 创建 private heap创建private heap的收益是什么可以在用户态直接获取 IPC 通信对象的状态。在实时进程初始化的过程中用户态初始化代码会打开/dev/rtdm/memdev-private设备文件并通过 RTDM 接口将private heap的内核空间映射到用户空间得到的用户态地址存入指针变量cobalt_umm_private。cobalt_umm_private map_umm(COBALT_MEMDEV_PRIVATE, private_size);以信号量为例阐述如何在用户态获取信号量的状态信息内核态在内核态初始化信号的时候信号量的状态信息存放在私有堆private heap中信号量的state_offset存放其状态信息相对于私有堆起始地址的偏移地址。__cobalt_sem_init - state cobalt_umm_alloc(sys_ppd-umm, sizeof(*state)); - sm-state_offset cobalt_umm_offset(sys_ppd-umm, sem-state);用户态在用户态通过私有堆private heap在用户态的地址 cobalt_umm_private 加上信号量的state_offset就可以直接获取信号量的状态信息。sem_get_state - return cobalt_umm_private shadow-state_offset;7.5.3 shared heapshared heap是 Cobalt 实时内核在内核空间专用于存放实时线程状态信息大小为CONFIG_XENO_OPT_SHARED_HEAPSZ默认值为 256KB。实时线程是由 Cobalt 实时内核全局管理的所有的实时线程都使用同一个shared heap所以也称为共享堆。共享堆shared heap的创建时机是在 Cobalt 实时内核的内核空间。在 Cobalt 实时内核初始化过程中调用cobalt_memdev_init函数创建的。共享堆shared heap创建后由全局变量struct cobalt_ppd cobalt_kernel_ppd的umm成员变量管理。xenomai_init 内核态 - cobalt_memdev_init - cobalt_umm_init 创建 shared heap创建shared heap的收益是什么可以在用户态直接获取实时线程的状态。在内核态创建实时线程时从shared heap分配struct xnthread_user_window u_window结构体实体并将此结构体实体的地址相对于 shared heap 的偏移地址返回到用户态u_winoff变量。struct xnthread_user_window { __u32 state; __u32 info; __u32 grant_value; __u32 pp_pending; };在用户态使用 RTDM 接口打开/dev/rtdm/memdev-shared设备文件并把shared heap的内核空间映射到用户空间得到的用户态地址存入指针变量cobalt_umm_shared。最后通过cobalt_umm_shared u_winoff就可以从用户态直接访问到内核态的thread-u_window无需通过系统调用保证实时性。cobalt_umm_shared map_umm(COBALT_MEMDEV_SHARED, size);7.5.4 debug logCobalt 实时内核支持在内核空间追踪relax信息并输出到用户空间。具体的代码在kernel/cobalt/debug.c中。此内核功能的详细信息在其它章节详细阐述。在init_trace_relax函数中初始化了一个名为debug log的堆大小为CONFIG_XENO_OPT_DEBUG_TRACE_LOGSZ * 1024。在 xndebug_trace_relax 函数中从debug log堆中分配内存struct relax_record用于记录 relax 的 backtrace 信息然后插入链表 relax_record_list 中。xndebug_trace_relax p xnheap_alloc(memory_pool, sizeof(*p));