Slab

slabtop

Linux内核需要为临时对象如任务或者设备结构和节点分配内存,缓存分配器管理着这些类型对象的缓存。现代Linux内核部署了该缓存分配器以持有缓存,称之为片。不同类型的片缓存由片分配器维护。
slabtop命令的作用就是显示实时内核片缓存信息。

my Ubuntu

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
root@m:/boot# ack SLUB
config-5.4.0-26-generic
247:CONFIG_SLUB_DEBUG=y
248:CONFIG_SLUB_MEMCG_SYSFS_ON=y
251:CONFIG_SLUB=y
257:CONFIG_SLUB_CPU_PARTIAL=y
10222:# CONFIG_SLUB_DEBUG_ON is not set
10223:# CONFIG_SLUB_STATS is not set
root@m:/boot#
root@m:/boot# ack SLAB
config-5.4.0-26-generic
250:# CONFIG_SLAB is not set
253:CONFIG_SLAB_MERGE_DEFAULT=y
254:CONFIG_SLAB_FREELIST_RANDOM=y
255:CONFIG_SLAB_FREELIST_HARDENED=y

difference between SLAB and SLUB

LAB 分配器多年以来一直位于 Linux 内核的内存管理部分的核心地带,内核黑客们一般不愿意主动去更改它的代码,因为它实在是非常复杂,而且在大多数情况下,它的工作完成的相当不错。但是,随着大规模多处理器系统和 NUMA系统的广泛应用,SLAB 分配器逐渐暴露出自身的严重不足:

  • 较多复杂的队列管理。在 SLAB 分配器中存在众多的队列,例如针对处理器的本地对象缓存队列,slab 中空闲对象队列,每个 slab 处于一个特定状态的队列中,甚至缓冲区控制结构也处于一个队列之中。有效地管理这些不同的队列是一件费力且复杂的工作。

  • slab 管理数据和队列的存储开销比较大。每个 slab 需要一个 struct slab 数据结构和一个管理所有空闲对象的 kmem_bufctl_t(4 字节的无符号整数)的数组。当对象体积较少时,kmem_bufctl_t 数组将造成较大的开销(比如对象大小为32字节时,将浪费 1/8 的空间)。为了使得对象在硬件高速缓存中对齐和使用着色策略,还必须浪费额外的内存。同时,缓冲区针对节点和处理器的队列也会浪费不少内存。测试表明在一个 1000 节点/处理器的大规模 NUMA 系统中,数 GB 内存被用来维护队列和对象的引用。

  • 缓冲区内存回收比较复杂。

  • 对 NUMA 的支持非常复杂。SLAB 对 NUMA 的支持基于物理页框分配器,无法细粒度地使用对象,因此不能保证处理器级缓存的对象来自同一节点。
    冗余的 Partial 队列。SLAB 分配器针对每个节点都有一个 Partial 队列,随着时间流逝,将有大量的 Partial slab 产生,不利于内存的合理使用。

  • 性能调优比较困难。针对每个 slab 可以调整的参数比较复杂,而且分配处理器本地缓存时,不得不使用自旋锁。
    调试功能比较难于使用。

为了解决以上 SLAB 分配器的不足之处,内核开发人员 Christoph Lameter 在 Linux 内核 2.6.22 版本中引入一种新的解决方案:SLUB 分配器。SLUB 分配器特点是简化设计理念,同时保留 SLAB 分配器的基本思想:每个缓冲区由多个小的 slab 组成,每个 slab 包含固定数目的对象。SLUB 分配器简化了kmem_cache,slab 等相关的管理数据结构,摒弃了SLAB 分配器中众多的队列概念,并针对多处理器、NUMA 系统进行优化,从而提高了性能和可扩展性并降低了内存的浪费。为了保证内核其它模块能够无缝迁移到 SLUB 分配器,SLUB 还保留了原有 SLAB 分配器所有的接口 API 函数。

reference

知乎.谈slab

Cache占用过多内存导致Linux系统内存不足问题排查

Android Studio

Android Studio 编写Android APK

目标设备和Android Studio的PC通过USB直接连接或者WIFI连接(WIFI ADB)

AVD: 需要下载目标平台的镜像

公司内部禁止访问Android和谷歌官网导致AndroidStudio功能不完整, 无法编译一个APK.

Android


Android 的启动流程

Android 的init进程

Android的Zygote进程

SystemServer进程

ActivityManagerService

Launcher

Binder

Telephony

TelephonyManager

java/android/telephony/TelephonyManager.java

Ftrace

内核源码位置 src/kernel/trace:

/sys/kernel/debug/tracing

root@v:/sys/kernel/debug/tracing# ls
available_events            events                    per_cpu              set_ftrace_notrace  trace                tracing_on
available_filter_functions  free_buffer               printk_formats       set_ftrace_pid      trace_clock          tracing_thresh
available_tracers           function_profile_enabled  README               set_graph_function  trace_marker         uprobe_events
buffer_size_kb              instances                 saved_cmdlines       set_graph_notrace   trace_options        uprobe_profile
buffer_total_size_kb        kprobe_events             saved_cmdlines_size  snapshot            trace_pipe
current_tracer              kprobe_profile            set_event            stack_max_size      trace_stat
dyn_ftrace_total_info       max_graph_depth           set_event_pid        stack_trace         tracing_cpumask
enabled_functions           options                   set_ftrace_filter    stack_trace_filter  tracing_max_latency



buffer_size_kb:这个属性比較重要,也是使用中须要注意的,这是设置启动的CPU的缓存大小。取决于追踪log的大小,超出会反复利用覆盖,可是一次性分配又须要考虑内存。
buffer_total_size_kb:这个就是总和buffer size 了,启用了多少个cpu去trace就乘以buffer_size_kb.
current_tracer: 当前的追踪器。有哪几种能够查看available_tracers ,用echo * > 重定向 设置改变,详细tracer的不同需另行參考 ,默觉得nop
events:文件夹下就是加入在kernel源代码中已经存在的各个event集合。
free_buffer:顾名思义,可是这个使用方法比較特殊,有仅仅要open之后。等处理完buffer之后 close这个文件就可以释放buffer,有兴趣能够去trace.c里面看看这个节点的file_operation,不手动去close这个节点的话,上面设置的buffer是不会free的。
trace:用于追踪操作的文件节点,就是读取该节点获取trace log
tracing_cpumask:用到的cpu标记。以数值bit位表示多少个cpu,这个尤为注意。比方四核 cat显示就是 f 也就是1111。
tracing_on:开关