以下是根据聊天内容整理的技术文档,涵盖 Linux 内存管理、内核页表、任务状态段(TSS)等核心机制:


Linux 内存管理与内核机制总结

1. 内存区域(Zones)

1.1 32 位系统的内存划分

| Zone | 物理地址范围 | 虚拟地址范围 | 用途 | |—————-|———————–|———————–|—————————–| | ZONE_DMA | 0x00000000 - 0x00FFFFFF | 0xC0000000 - 0xC0FFFFFF | DMA 设备专用内存(16MB) | | ZONE_NORMAL | 0x01000000 - 0x37FFFFFF | 0xC1000000 - 0xF7FFFFFF | 常规内核和用户内存(880MB) | | ZONE_HIGHMEM | 0x38000000 - 物理内存末尾 | 动态映射(kmap) | 超出 896MB 的物理内存 |

1.2 64 位系统的变化

  • ZONE_HIGHMEM:所有物理内存通过直接映射区(0xFFFF800000000000 起)线性映射。
  • ZONE_DMAZONE_DMA32:保留用于兼容 DMA 设备。

2. 物理内存分配

2.1 alloc_pages

  • 功能:分配连续的物理页。
  • 特性
    • 返回 2^order 个整数页(如 order=2 分配 4 页)。
    • 物理地址连续,通过 Buddy Allocator 实现。
  • 示例
    struct page *page = alloc_pages(GFP_KERNEL, 2); // 分配 4 页(16KB)
    

2.2 vmallockmap

| 机制 | 虚拟地址范围 | 物理内存来源 | 用途 | |—————-|——————————-|———————–|—————————–| | vmalloc | 0xF8000000 - 0xFFFFFFFF(32 位) | 非连续物理页 | 大块非连续内存分配 | | kmap | 0xFFC00000 - 0xFFE00000(Fixmap) | ZONE_HIGHMEM | 临时映射高端内存 |


3. 内核页表管理

3.1 直接映射区(Direct Map)

  • 64 位系统:所有物理内存通过固定偏移(如 0xFFFF800000000000)线性映射。
  • 页表项数量:与物理内存容量相关(页表项数 = 物理内存大小 / 页大小)。

3.2 页表层级(x86_64)

| 层级 | 覆盖范围 | 条目数 | 作用 | |—————-|——————-|———–|—————————–| | PML4 | 512GB | 512 | 顶级页表 | | PDPT | 1GB | 512 | 二级页表 | | PD | 2MB | 512 | 三级页表 | | PT | 4KB | 512 | 四级页表(最终映射到物理页) |


4. 任务状态段(TSS)

4.1 关键字段

| 字段 | 作用 | |———-|————————————————————————-| | esp0 | 内核栈指针,用户态→内核态切换时更新栈。 | | ss0 | 内核栈段寄存器(通常为 __KERNEL_DS)。 | | cr3 | 页目录基址,任务切换时更新以实现地址空间隔离。 |

4.2 任务切换流程

  1. 保存当前任务的寄存器状态到 TSS。
  2. 加载新任务的 cr3(切换页表)。
  3. 更新 esp0ss0(切换内核栈)。
  4. 恢复新任务的寄存器状态。

5. 用户态内存分配

5.1 mmap 匿名页分配

  • 物理内存来源:优先从 ZONE_NORMAL 分配,不足时使用 ZONE_HIGHMEM
  • 页表项:用户态虚拟地址必须通过页表映射到物理页(缺页异常触发分配)。

5.2 Buddy Allocator

  • 每个 Zone 独立ZONE_DMAZONE_NORMAL 等均有独立的 Buddy Allocator 管理空闲页。
  • 分配优先级ZONE_DMA → ZONE_NORMAL → ZONE_HIGHMEM(32 位)。

6. 关键结论

  1. 32 位系统ZONE_HIGHMEM 用于访问超出 896MB 的内存,需动态映射。
  2. 64 位系统:无 ZONE_HIGHMEM,所有物理内存直接映射。
  3. DMA Zone:前 4MB 可分配,除非被 BIOS 保留。
  4. 任务切换:TSS 的 esp0ss0cr3 是实现内核栈和地址空间隔离的核心。

附录:常用命令

# 查看内存区域信息
cat /proc/zoneinfo

# 查看内核虚拟地址映射
cat /proc/vmallocinfo

# 查看页表统计
grep "DirectMap" /proc/meminfo

本文档可作为 Linux 内存管理和内核机制的快速参考指南。

Linux 中的 xarray 及其 API 使用详解

xarray 是 Linux 内核中一个高效、线程安全且适用于稀疏数据存储的数据结构。它从 Linux v4.20 版本开始引入,目的是取代旧的 radix_treeidr 接口,提供更统一、更易用、更高效的键值对管理方式。

本文将详细介绍 xarray 的概念、设计初衷以及如何在内核模块或系统编程中使用它的主要 API。


🔍 什么是 xarray

xarray 是一种基于基数树(radix tree)优化的稀疏数组实现。它用于将 64 位整数索引(index) 映射为任意指针(void *),非常适合处理:

  • 文件页缓存(page cache)
  • ID 到指针的映射
  • 虚拟内存区域(VMA)跟踪
  • 设备驱动资源管理

📌 主要特性

特性 描述
✅ 稀疏存储 只存储有内容的位置,节省内存
✅ 支持 64 位索引 支持非常大的索引空间(0 ~ 2^64 -1)
✅ 线程安全 支持并发访问,无需额外加锁
✅ 统一接口 替代了 radix_treeidr
✅ 标记支持(Tags) 类似于 radix_tree 的标签机制
✅ 预分配支持 支持原子上下文中的操作

🧠 为什么引入 xarray

xarray 出现之前,Linux 内核广泛使用以下两种结构来处理键值映射:

  • radix_tree:用于 page cache 和其他稀疏数组,但接口复杂,需手动加锁。
  • idr:用于将整数 ID 映射为指针,但功能有限。

因此,xarray 应运而生,融合了两者的优势:

  • 性能与 radix_tree 相当甚至更好
  • 接口简洁统一,易于使用
  • 支持并发访问和迭代器
  • 更好的错误处理机制

🧱 核心数据结构

struct xarray {
    unsigned long xa_flags;
    void *xa_head;
    gfp_t xa_gfp_mask;
};
  • xa_head:指向内部树结构的根节点
  • xa_flags:控制行为(如是否允许中断上下文分配内存)
  • xa_gfp_mask:分配内存时使用的标志位

你可以通过宏定义声明一个 xarray

XARRAY(my_xa, XA_FLAGS_ALLOC);  // 定义并初始化一个 xarray

🧪 常用 API 操作

以下是 xarray 最常用的几个接口函数:

1. 插入/更新条目

int xa_store(struct xarray *xa, unsigned long index,
             void *entry, gfp_t gfp);

示例:

xa_store(&my_xa, 123, my_pointer, GFP_KERNEL);

2. 读取条目

void *xa_load(struct xarray *xa, unsigned long index);

示例:

void *ptr = xa_load(&my_xa, 123);

3. 删除条目

void xa_erase(struct xarray *xa, unsigned long index);

示例:

xa_erase(&my_xa, 123);

4. 原子替换

void *xa_cmpxchg(struct xarray *xa, unsigned long index,
                 void *old, void *store, gfp_t gfp);

示例:

xa_cmpxchg(&my_xa, 123, old_ptr, new_ptr, GFP_KERNEL);

5. 自动分配索引

int xa_alloc(struct xarray *xa, u32 *id, void *entry,
             struct xa_limit limit, gfp_t gfp);

示例:

u32 id;
xa_alloc(&my_xa, &id, ptr, XA_LIMIT(0, 1000), GFP_KERNEL);

6. 遍历所有有效项

unsigned long index;
void *entry;

xa_for_each (&my_xa, index, entry) {
    printk(KERN_INFO "Index %lu: %p\n", index, entry);
}

⚙️ 锁机制与并发控制

xarray 提供了多种访问模式以支持多线程场景:

模式 是否需要锁 适用场景
GFP_KERNEL 默认模式
GFP_ATOMIC 中断上下文
XA_TRYLOCK 多线程写入时手动加锁

你也可以使用如下宏进行手动加锁:

unsigned long flags;

xa_lock_irqsave(&my_xa, flags);
... // 修改 xarray
xa_unlock_irqrestore(&my_xa, flags);

📦 在 Linux 内核中的典型应用场景

1. Page Cache 管理

替代了传统的 radix_tree,用于管理文件对应的内存页缓存:

struct address_space {
    struct xarray i_pages;   // 替代原来的 radix_tree
    ...
};
  • 用偏移量作为 key
  • 存储 struct page *struct folio *

2. IDR 替代

完全替代 idr 接口,用于整数 ID 到指针的映射:

XARRAY(my_xa, XA_FLAGS_ALLOC);
DEFINE_XARRAY_FLAGS(my_xa, XA_FLAGS_ALLOC); // for newer versions

// 分配新 ID 并关联指针
unsigned long id;
void *ptr = kmalloc(...);

int ret = xa_alloc(&my_xa, &id, ptr, XA_LIMIT(0, 1000), GFP_KERNEL);

3. 设备驱动中的句柄管理

许多设备驱动使用 xarray 来管理:

  • GPU 对象(如 DRM/KMS)
  • 内存区域(memory regions)
  • 文件描述符映射等资源

🧩 使用 xarray 的优势

优点 描述
✅ 高效查找/插入/删除 O(log n) 时间复杂度
✅ 稀疏索引 不浪费内存
✅ 线程安全 支持并发访问
✅ 接口统一 替代多个旧接口
✅ 迭代器支持 强大且易用
✅ 更适合现代内核 支持标记、预分配等扩展功能

🧪 示例代码(内核模块)

#include <linux/module.h>
#include <linux/xarray.h>

MODULE_LICENSE("GPL");

// XARRAY(my_xa, XA_FLAGS_ALLOC);
DEFINE_XARRAY_FLAGS(my_xa, XA_FLAGS_ALLOC);

static int __init my_init(void)
{
    void *ptr = kmalloc(1024, GFP_KERNEL);
    unsigned long index = 123;

    xa_store(&my_xa, index, ptr, GFP_KERNEL);

    void *entry = xa_load(&my_xa, index);
    pr_info("Loaded: %p\n", entry);

    xa_for_each (&my_xa, index, entry) {
        pr_info("Found index %lu: %p\n", index, entry);
    }

    return 0;
}

static void __exit my_exit(void)
{
    unsigned long index;
    void *entry;

    xa_for_each (&my_xa, index, entry) {
        kfree(entry);
        xa_erase(&my_xa, index);
    }
}

module_init(my_init);
module_exit(my_exit);

📈 性能优势对比(vs radix_tree)

特性 radix_tree xarray
接口一致性 ❌ 分散 ✅ 统一
并发支持 ❌ 需外部锁 ✅ 内置并发控制
迭代器支持 ❌ 不友好 ✅ 强大迭代器
错误处理 ❌ 复杂 ✅ 清晰返回码
扩展能力 ❌ 困难 ✅ 易于添加新特性

🧩 总结

属性 描述
名称 xarray
类型 稀疏键值映射结构
底层结构 基于基数树优化
主要用途 page cache、IDR、资源管理
索引类型 64-bit 整数
数据类型 void *(可包含 tag)
线程安全性 ✅ 支持并发访问
内核版本引入 v4.20+
当前状态 已广泛替代旧结构(v5.x ~ v6.x)

struct address_space 是做什么的?

这是 Linux 内核中一个非常重要且核心的数据结构,它在文件系统、内存管理、虚拟内存子系统等多个模块中都有广泛应用。


✅ 简短回答:

struct address_space 是 Linux 内核中用于描述 文件(或块设备)与内存之间的映射关系 的结构体。
它主要用于:

  • 管理文件的 page cache
  • 跟踪哪些进程将该文件 mmap 到自己的地址空间
  • 控制文件页的读写、回收、回写等操作

你可以把它理解为:"一个文件在内存中的缓存和使用状态" 的抽象表示。


📚 结构体定义(简化版)

以下是 struct address_space 的主要字段(Linux v6.x 中定义于 include/linux/fs.h):

struct address_space {
    struct inode        *host;       // 拥有这个 address_space 的 inode
    struct xarray       i_pages;     // 替代旧的 radix_tree,存储 page cache
    unsigned long       nrpages;     // 当前缓存的页数
    pgoff_t             writeback_index; // 下一个要写回磁盘的页索引
    const struct address_space_operations *a_ops; // 文件系统的操作函数指针
    struct mutex        invalidate_lock;  // 锁,保护 invalidate 操作
    struct rb_root_cached i_mmap;       // 所有映射该文件的 VMA(虚拟内存区域)
    ...
};

🔍 主要作用详解

1. 🗂️ 管理 Page Cache

  • i_pages 字段是一个 xarray(以前是 radix_tree),用来存储文件对应的缓存页(struct page *struct folio *)。
  • 每个文件都会有一个 address_space 实例,负责管理其所有被加载到内存中的页。

示例:

当你执行以下代码:

int fd = open("test.txt", O_RDONLY);
read(fd, buf, len);  // 读取内容

内核会把文件内容读入内存,并通过 address_space 来管理这些缓存页。


2. 🧠 追踪谁映射了这个文件(i_mmap

  • i_mmap 是一棵红黑树(rb_root),保存了所有将该文件 mmap 到进程地址空间的 VMA(Virtual Memory Area)。
  • 每当一个进程通过 mmap() 将文件映射进内存时,它的 VMA 就会被插入这棵树中。

示例:

当你执行:

void *addr = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, offset);

内核会创建一个 VMA 并添加到该文件的 i_mmap 树中。


3. 🔄 支持文件回写(writeback)

  • writeback_index 字段记录下一个需要写回到磁盘的页索引。
  • 如果文件被修改(如调用 write() 或 mmap 后修改内容),这些脏页会标记为 dirty,并由内核的 pdflush / kthread 在适当时候写回磁盘。

4. 🧱 提供文件系统的操作接口(a_ops

  • a_ops 是一个函数指针表,指向一组文件系统提供的操作函数,例如:
    • readpage() —— 从磁盘读一页内容
    • writepage() —— 把一页内容写回磁盘
    • set_page_dirty() —— 标记页为脏
    • releasepage() —— 页面释放时的操作

不同文件系统(ext4、tmpfs、proc、sysfs 等)可以实现自己的 address_space_operations


5. 🔐 同步锁机制(如 invalidate_lock

  • invalidate_lock 用于保护对 i_pages 的清理操作(如截断文件或调用 posix_fadvise(... DONTNEED))。
  • 防止在清理缓存时发生并发访问错误。

🧩 与其他结构的关系图解

struct file
     ↓
struct inode
     ↓
struct address_space   ←—— (this is what we're talking about!)
     ↓
struct xarray i_pages → 存储文件的 page cache
     ↓
struct rb_root_cached i_mmap → 记录哪些进程 mmap 了这个文件

所以:

  • 一个 file 对应一个 inode
  • 一个 inode 包含一个 address_space
  • address_space 管理 page cache 和内存映射

🧪 典型应用场景

场景 如何使用 address_space
文件读取 缓存页通过 address_space 管理
文件写入 修改的页标记为 dirty,后续异步写回
mmap 映射 VMA 添加到 i_mmap 红黑树
截断文件 清除对应 address_space 中的页
页面回收(reclaim) 检查 i_mmap 判断是否可回收
用户调用 posix_fadvise(... POSIX_FADV_DONTNEED) 调用 invalidate_inode_pages2() 清空 cache

🧠 常见误区澄清

误解 正确认识
address_space 只用于文件 ❌ 它也用于设备、共享内存等场景
address_space 管理整个文件的内容 ❌ 它只管理当前被缓存或映射的部分
它是 per-process 的 ❌ 它是 per-inode 的,多个进程共享同一个 address_space
它和用户空间有关 ❌ 它是完全的内核结构,不暴露给用户

🧪 示例代码片段(内核模块)

struct address_space *mapping = file->f_mapping;

// 获取文件大小
loff_t size = i_size_read(mapping->host);

// 查看当前缓存了多少页
pr_info("Cached pages: %lu\n", mapping->nrpages);

// 遍历所有缓存页(简化版)
unsigned long index = 0;
while (index < mapping->nrpages) {
    struct page *page = read_cache_page(mapping, index, NULL, NULL);
    if (!IS_ERR(page)) {
        pr_info("Page at %lu loaded\n", index);
        put_page(page);
    }
    index++;
}

📌 总结

功能 描述
名称 struct address_space
所属结构 struct inode
主要用途 管理文件的 page cache 和内存映射
核心字段 i_pages(缓存页)、i_mmap(VMA 树)
文件系统支持 通过 a_ops 接口实现
使用场景 mmap、read/write、truncate、reclaim、sync
重要性 ⭐⭐⭐⭐⭐(非常核心)

🧩 想进一步了解?

如果你感兴趣,我可以为你提供:

  • address_space 的完整源码分析(v6.x)
  • 如何编写一个内核模块来遍历 i_pagesi_mmap
  • address_space 在 tmpfs、ext4、ramfs 等文件系统中的差异
  • 用户程序如何影响 address_space 的行为(如 mmap、readahead)

欢迎继续提问!

/proc//pagemap的格式是什么?

/proc/<pid>/pagemap 是 Linux 内核提供的一种机制,用于从用户空间访问进程的物理内存映射信息。它允许你查询某个虚拟地址是否被映射、对应的物理页帧号(PFN)、是否是脏页、是否被修改等。


🧾 /proc/<pid>/pagemap 的格式说明

✅ 文件路径:

/proc/<pid>/pagemap
  • 每个进程都有一个对应的 pagemap 文件。
  • 它是一个只读二进制文件。
  • 每个虚拟页对应 8 字节(64位)的数据结构。

📚 每个条目(每个虚拟页)的格式(共 64 位)

名称 含义
0 present 页是否在内存中(1 = 存在,0 = 不存在)
1 swapped 是否被交换到 swap(1 = 被换出)
2-54 pfn 物理页帧号(Page Frame Number),如果 present=1
55 soft_dirty 该页是否被标记为"soft dirty"(用于追踪 fork 后的写操作)
56 file_page 1 表示这是一个文件映射页(非匿名页)
57 swapped_shared 如果设置了 swapped,表示这个页属于共享内存(如 tmpfs 或 shm)
58-60 page_idle idle 标志(用于 idle tracking)
61-63 flags 预留字段

⚠️ 注意:并不是所有位都在所有内核版本中都可用,具体支持取决于你的内核配置。


🔍 示例解释:

假设你读取了 8 字节的内容,其值为:

0x7F00000000000123

你可以将其拆分为:

二进制:0111 1111 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 0010 0011
        ^^^^^^^^ ...                                         ^^^^^^^^^^^^^^^^^^
        保留位                                               PFN (低 52 位)
        present = 1, swapped = 0, file_page = 0 ...

这意味着:

  • 该页存在(present = 1)
  • 未被交换出去(swapped = 0)
  • 是匿名页(file_page = 0)
  • 对应的物理页帧号是 0x123(即 291)
  • 页面大小通常是 4KB,所以对应的物理地址是 0x123 * 4096

🛠️ 如何使用 /proc/<pid>/pagemap

步骤:

  1. 获取进程的虚拟地址范围
    使用 /proc/<pid>/maps 获取进程的虚拟内存区域(VMA)。

  2. 计算需要读取的偏移量
    每个虚拟页对应一个 8 字节的条目,所以偏移量是:
    offset = virtual_page_number * sizeof(uint64_t)
    
  3. 读取 pagemap 条目
    使用 pread() 函数读取指定偏移处的 8 字节数据。

  4. 解析标志位和 PFN

💡 示例代码(C语言)

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdint.h>

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <pid> <virtual_addr>\n", argv[0]);
        return -1;
    }

    pid_t pid = atoi(argv[1]);
    uint64_t vaddr = strtoull(argv[2], NULL, 16);

    // 获取系统页面大小
    uint64_t pagesize = getpagesize();
    uint64_t vpn = vaddr / pagesize;

    // 打开 pagemap
    char pagemap_path[256];
    snprintf(pagemap_path, sizeof(pagemap_path), "/proc/%d/pagemap", pid);
    int fd = open(pagemap_path, O_RDONLY);
    if (fd < 0) {
        perror("open");
        return -1;
    }

    // 定位到对应的 pagemap entry
    uint64_t entry;
    off_t offset = vpn * sizeof(entry);
    ssize_t bytes_read = pread(fd, &entry, sizeof(entry), offset);
    if (bytes_read != sizeof(entry)) {
        perror("pread");
        close(fd);
        return -1;
    }

    // 解析 entry
    uint64_t present = (entry >> 0) & 0x1;
    uint64_t pfn = (entry >> 0) & ((1ULL << 54) - 1); // 52-bit PFN
    uint64_t dirty = (entry >> 55) & 0x1; // 第 55 位是 soft-dirty(不是真正的 dirty)
    uint64_t file_page = (entry >> 56) & 0x1;

    printf("Present: %llu\n", present);
    printf("File page: %llu\n", file_page);
    printf("Soft Dirty: %llu\n", dirty);
    if (present)
        printf("Physical Frame Number (PFN): 0x%llx\n", (unsigned long long)pfn);

    close(fd);
    return 0;
}

🧪 如何运行上面的代码?

编译:

gcc pagemap.c -o pagemap

运行(例如查看进程 1234 中地址 0x7f00000000 的状态):

./pagemap 1234 7f00000000

📌 小贴士

  • 你需要 root 权限才能访问其他进程的 pagemap
  • 可以结合 /proc/<pid>/maps 获取进程的 VMA 区域;
  • pagemap 是调试内存行为的重要工具,常用于:
    • 分析内存泄漏
    • 监控 mmap 文件的缓存情况
    • 查看哪些页是脏页(需配合其他手段)

✅ 总结

内容 说明
文件位置 /proc/<pid>/pagemap
每个条目长度 8 字节(64 bit)
关键字段 present, pfn, dirty, file_page 等
用途 查看虚拟地址对应的物理页信息
用户态访问方式 使用 pread() 读取特定偏移处的数据
是否可以判断脏页? soft-dirty 是一种近似判断方法,但不是真实的 dirty flag

如果你想要一个 Python 实现的脚本或想了解如何结合 /proc/self/pagemap 做内存分析,我也可以继续为你提供完整代码。欢迎继续提问!

应用内存情况

小红书和UC

➜  ndk_template git:(master) ✗ adb shell /data/local/tmp/file_mem_stat 3554
  Present: 38105 pages (148.85 MB)
  Absent: 11627668 pages (45420.58 MB)

  FilePage: 32080 pages (125.31 MB)
    shared: 660 pages (2.58 MB)
    private: 31420 pages (122.73 MB)
    dirty: 0 pages (0.00 MB)
    clean: 32080 pages (125.31 MB)
    private & clean: 31420 pages (122.73 MB)
  NonFilePage: 6025 pages (23.54 MB)
Private File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Shared File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Anonymous Pages:
  Total: 6025 pages (23.54 MB)
Private File + Anonymous Total:
  Total: 6025 pages (23.54 MB)
➜  ndk_template git:(master) ✗ adb shell ps -ef | grep web
u10_i9023      721  4365 0 15:48:53 ?     00:00:00 com.google.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0
u10_i9024     3094  4365 0 15:49:06 ?     00:00:00 com.google.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0
u10_i9029     3586  4365 0 16:53:42 ?     00:00:00 com.google.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0
webview_zygote 4365 1524 0 19:47:02 ?     00:00:00 webview_zygote
u10_i9010     4618  4365 0 22:45:06 ?     00:00:01 com.google.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0
u10_i9030    10541  4365 0 17:03:02 ?     00:00:00 com.google.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0
u0_a181      12002  1524 0 19:48:00 ?     00:00:01 com.google.android.webview:webview_service
u10_a181     17181  1524 0 19:48:37 ?     00:00:02 com.google.android.webview:webview_service
u10_a309     17739  1524 2 16:20:51 ?     00:01:43 com.tencent.mm:xweb_privileged_process_0
u10_i9028    17766  1524 4 16:20:51 ?     00:02:40 com.tencent.mm:xweb_sandboxed_process_0:com.tencent.xweb.pinus.sdk.process.SandboxedProcessService
u10_i9031    19782  4365 0 17:17:30 ?     00:00:00 com.google.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0
u0_i9008     24902  4365 0 22:37:06 ?     00:00:01 com.google.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0
u10_a181     30125  1524 0 22:42:24 ?     00:00:01 com.google.android.webview:webview_apk
u10_i9032    31575  4365 1 17:31:26 ?     00:00:00 com.google.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0
➜  ndk_template git:(master) ✗ adb shell ps -ef | grep uc
root           613     2 0 19:46:39 ?     00:00:00 [cpucp_wq]
root          1239     2 0 19:46:41 ?     00:00:00 [xiaomi_touch_temp_thread]
root          1249     2 0 19:46:41 ?     00:00:00 [ipa_uc_holb_wq]
system        1915     1 1 19:46:48 ?     00:12:12 vendor.xiaomi.hw.touchfeature-service
root          2710     1 0 19:46:51 ?     00:00:10 toucheventcheck
u0_a123       5672  1524 0 22:48:34 ?     00:00:02 com.xiaomi.aicr:instruction
system        6986  1524 0 19:47:28 ?     00:00:01 com.xiaomi.touchservice
u10_a123     18369  1524 0 07:20:47 ?     00:00:01 com.xiaomi.aicr:instruction
u10_system   30535  1524 0 20:20:47 ?     00:00:01 com.miui.touchassistant
➜  ndk_template git:(master) ✗ adb shell ps -ef | grep UC
u10_a313      5499  1524 2 15:49:17 ?     00:01:37 com.UCMobile
u10_a313      6472  1524 0 22:50:10 ?     00:00:22 com.UCMobile:push
u10_a313     18948  1524 0 23:29:12 ?     00:00:24 com.UCMobile:DownloadService
u10_a313     32014  1524 0 22:42:32 ?     00:01:43 com.UCMobile:channel
u10_a313     32041  1524 32 17:31:29 ?    00:00:21 com.UCMobile:MediaPlayerService
u10_a313     32270  1524 2 17:31:30 ?     00:00:01 com.UCMobile:gpu_process
➜  ndk_template git:(master) ✗ adb shell /data/local/tmp/file_mem_stat 5499
  Present: 39477 pages (154.21 MB)
  Absent: 28020492 pages (109455.05 MB)

  FilePage: 33138 pages (129.45 MB)
    shared: 0 pages (0.00 MB)
    private: 33138 pages (129.45 MB)
    dirty: 0 pages (0.00 MB)
    clean: 33138 pages (129.45 MB)
    private & clean: 33138 pages (129.45 MB)
  NonFilePage: 6339 pages (24.76 MB)
Private File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 843 pages (3.29 MB)
Shared File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Anonymous Pages:
  Total: 6339 pages (24.76 MB)
Private File + Anonymous Total:
  Total: 7182 pages (28.05 MB)
➜  ndk_template git:(master) ✗ adb shell /data/local/tmp/file_mem_stat 6472
fopen maps: No such file or directory
➜  ndk_template git:(master) ✗ adb shell ps -ef | grep UC
u10_a313      5499  1524 3 15:49:17 ?     00:03:26 com.UCMobile
u10_a313      7813  1524 8 17:34:29 ?     00:00:01 com.UCMobile:push
u10_a313     18948  1524 0 23:29:12 ?     00:00:25 com.UCMobile:DownloadService
u10_a313     32014  1524 0 22:42:32 ?     00:01:44 com.UCMobile:channel
u10_a313     32041  1524 30 17:31:29 ?    00:01:00 com.UCMobile:MediaPlayerService
u10_a313     32270  1524 1 17:31:30 ?     00:00:02 com.UCMobile:gpu_process
➜  ndk_template git:(master) ✗ adb shell /data/local/tmp/file_mem_stat 7813
  Present: 20280 pages (79.22 MB)
  Absent: 5374178 pages (20992.88 MB)

  FilePage: 4288 pages (16.75 MB)
    shared: 0 pages (0.00 MB)
    private: 4288 pages (16.75 MB)
    dirty: 0 pages (0.00 MB)
    clean: 4288 pages (16.75 MB)
    private & clean: 4288 pages (16.75 MB)
  NonFilePage: 15992 pages (62.47 MB)
Private File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 58 pages (0.23 MB)
Shared File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Anonymous Pages:
  Total: 15992 pages (62.47 MB)
Private File + Anonymous Total:
  Total: 16050 pages (62.70 MB)
➜  ndk_template git:(master) ✗ adb shell /data/local/tmp/file_mem_stat 18948
  Present: 12177 pages (47.57 MB)
  Absent: 5328891 pages (20815.98 MB)

  FilePage: 2661 pages (10.39 MB)
    shared: 1 pages (0.00 MB)
    private: 2660 pages (10.39 MB)
    dirty: 0 pages (0.00 MB)
    clean: 2661 pages (10.39 MB)
    private & clean: 2660 pages (10.39 MB)
  NonFilePage: 9516 pages (37.17 MB)
Private File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Shared File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Anonymous Pages:
  Total: 9516 pages (37.17 MB)
Private File + Anonymous Total:
  Total: 9516 pages (37.17 MB)
➜  ndk_template git:(master) ✗ adb shell /data/local/tmp/file_mem_stat 32014
  Present: 13847 pages (54.09 MB)
  Absent: 5329788 pages (20819.48 MB)

  FilePage: 4791 pages (18.71 MB)
    shared: 2 pages (0.01 MB)
    private: 4789 pages (18.71 MB)
    dirty: 0 pages (0.00 MB)
    clean: 4791 pages (18.71 MB)
    private & clean: 4789 pages (18.71 MB)
  NonFilePage: 9056 pages (35.38 MB)
Private File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Shared File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Anonymous Pages:
  Total: 9056 pages (35.38 MB)
Private File + Anonymous Total:
  Total: 9056 pages (35.38 MB)
➜  ndk_template git:(master) ✗ adb shell /data/local/tmp/file_mem_stat 32041
  Present: 22990 pages (89.80 MB)
  Absent: 5444300 pages (21266.80 MB)

  FilePage: 5660 pages (22.11 MB)
    shared: 0 pages (0.00 MB)
    private: 5660 pages (22.11 MB)
    dirty: 0 pages (0.00 MB)
    clean: 5660 pages (22.11 MB)
    private & clean: 5660 pages (22.11 MB)
  NonFilePage: 17330 pages (67.70 MB)
Private File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 1 pages (0.00 MB)
Shared File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Anonymous Pages:
  Total: 17330 pages (67.70 MB)
Private File + Anonymous Total:
  Total: 17331 pages (67.70 MB)
➜  ndk_template git:(master) ✗ adb shell /data/local/tmp/file_mem_stat 32270
  Present: 10169 pages (39.72 MB)
  Absent: 8933569 pages (34896.75 MB)

  FilePage: 3888 pages (15.19 MB)
    shared: 0 pages (0.00 MB)
    private: 3888 pages (15.19 MB)
    dirty: 0 pages (0.00 MB)
    clean: 3888 pages (15.19 MB)
    private & clean: 3888 pages (15.19 MB)
  NonFilePage: 6281 pages (24.54 MB)
Private File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Shared File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Anonymous Pages:
  Total: 6281 pages (24.54 MB)
Private File + Anonymous Total:
  Total: 6281 pages (24.54 MB)

腾讯(QQ + 微信)


➜  ndk_template git:(master) ✗ adb shell ps -ef | grep tencent
u0_a172       7181  1524 0 19:47:30 ?     00:00:01 com.tencent.soter.soterserver
u10_a302     16080  1524 0 19:48:32 ?     00:03:46 com.tencent.mobileqq:MSF
u10_a309     17237  1524 1 16:20:50 ?     00:01:00 com.tencent.mm:appbrand1
u10_a309     17739  1524 2 16:20:51 ?     00:01:43 com.tencent.mm:xweb_privileged_process_0
u10_i9028    17766  1524 3 16:20:51 ?     00:02:40 com.tencent.mm:xweb_sandboxed_process_0:com.tencent.xweb.pinus.sdk.process.SandboxedProcessService
u10_a309     18194  1524 0 19:48:42 ?     00:03:41 com.tencent.mm:push
u10_a309     23765  1524 1 23:06:09 ?     00:15:13 com.tencent.mm
u10_a302     29021  1524 0 22:42:01 ?     00:02:40 com.tencent.mobileqq
u10_a172     30085  1524 0 16:30:39 ?     00:00:00 com.tencent.soter.soterserver
➜  ndk_template git:(master) ✗ adb shell /data/local/tmp/file_mem_stat 29021
  Present: 20674 pages (80.76 MB)
  Absent: 1096464 pages (4283.06 MB)

  FilePage: 9873 pages (38.57 MB)
    shared: 37 pages (0.14 MB)
    private: 9836 pages (38.42 MB)
    dirty: 0 pages (0.00 MB)
    clean: 9873 pages (38.57 MB)
    private & clean: 9836 pages (38.42 MB)
  NonFilePage: 10801 pages (42.19 MB)
Private File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 2 pages (0.01 MB)
Shared File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 5 pages (0.02 MB)
Anonymous Pages:
  Total: 10801 pages (42.19 MB)
Private File + Anonymous Total:
  Total: 10803 pages (42.20 MB)
➜  ndk_template git:(master) ✗ adb shell /data/local/tmp/file_mem_stat 16080
  Present: 14276 pages (55.77 MB)
  Absent: 1374243 pages (5368.14 MB)

  FilePage: 8026 pages (31.35 MB)
    shared: 6 pages (0.02 MB)
    private: 8020 pages (31.33 MB)
    dirty: 0 pages (0.00 MB)
    clean: 8026 pages (31.35 MB)
    private & clean: 8020 pages (31.33 MB)
  NonFilePage: 6250 pages (24.41 MB)
Private File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Shared File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Anonymous Pages:
  Total: 6250 pages (24.41 MB)
Private File + Anonymous Total:
  Total: 6250 pages (24.41 MB)
➜  ndk_template git:(master) ✗ adb shell /data/local/tmp/file_mem_stat 18194
  Present: 17877 pages (69.83 MB)
  Absent: 1121092 pages (4379.27 MB)

  FilePage: 8268 pages (32.30 MB)
    shared: 1 pages (0.00 MB)
    private: 8267 pages (32.29 MB)
    dirty: 0 pages (0.00 MB)
    clean: 8268 pages (32.30 MB)
    private & clean: 8267 pages (32.29 MB)
  NonFilePage: 9609 pages (37.54 MB)
Private File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 1160 pages (4.53 MB)
Shared File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Anonymous Pages:
  Total: 9609 pages (37.54 MB)
Private File + Anonymous Total:
  Total: 10769 pages (42.07 MB)
➜  ndk_template git:(master) ✗ adb shell /data/local/tmp/file_mem_stat 17739
fopen maps: No such file or directory
➜  ndk_template git:(master) ✗ adb shell ps -ef | grep tencent
u0_a172       7181  1524 0 19:47:29 ?     00:00:01 com.tencent.soter.soterserver
u10_a302     16080  1524 0 19:48:31 ?     00:03:48 com.tencent.mobileqq:MSF
u10_a309     17237  1524 1 16:20:49 ?     00:01:02 com.tencent.mm:appbrand1
u10_a309     18194  1524 0 19:48:41 ?     00:03:44 com.tencent.mm:push
u10_a309     21857  1524 16 17:45:03 ?    00:00:05 com.tencent.mm:appbrand0
u10_a309     23765  1524 1 23:06:08 ?     00:15:24 com.tencent.mm
u10_a302     29021  1524 0 22:42:00 ?     00:02:45 com.tencent.mobileqq
u10_a172     30085  1524 0 16:30:38 ?     00:00:00 com.tencent.soter.soterserver
➜  ndk_template git:(master) ✗ adb shell /data/local/tmp/file_mem_stat 17237
  Present: 21838 pages (85.30 MB)
  Absent: 28056627 pages (109596.20 MB)

  FilePage: 9109 pages (35.58 MB)
    shared: 218 pages (0.85 MB)
    private: 8891 pages (34.73 MB)
    dirty: 0 pages (0.00 MB)
    clean: 9109 pages (35.58 MB)
    private & clean: 8891 pages (34.73 MB)
  NonFilePage: 12729 pages (49.72 MB)
Private File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 2 pages (0.01 MB)
Shared File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Anonymous Pages:
  Total: 12729 pages (49.72 MB)
Private File + Anonymous Total:
  Total: 12731 pages (49.73 MB)
➜  ndk_template git:(master) ✗ adb shell /data/local/tmp/file_mem_stat 21857
  Present: 29913 pages (116.85 MB)
  Absent: 91882645 pages (358916.58 MB)

  FilePage: 18002 pages (70.32 MB)
    shared: 0 pages (0.00 MB)
    private: 18002 pages (70.32 MB)
    dirty: 0 pages (0.00 MB)
    clean: 18002 pages (70.32 MB)
    private & clean: 18002 pages (70.32 MB)
  NonFilePage: 11911 pages (46.53 MB)
Private File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Shared File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Anonymous Pages:
  Total: 11911 pages (46.53 MB)
Private File + Anonymous Total:
  Total: 11911 pages (46.53 MB)
➜  ndk_template git:(master) ✗ adb shell /data/local/tmp/file_mem_stat 30085
  Present: 6406 pages (25.02 MB)
  Absent: 708605 pages (2767.99 MB)

  FilePage: 102 pages (0.40 MB)
    shared: 0 pages (0.00 MB)
    private: 102 pages (0.40 MB)
    dirty: 0 pages (0.00 MB)
    clean: 102 pages (0.40 MB)
    private & clean: 102 pages (0.40 MB)
  NonFilePage: 6304 pages (24.62 MB)
Private File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 2 pages (0.01 MB)
Shared File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Anonymous Pages:
  Total: 6304 pages (24.62 MB)
Private File + Anonymous Total:
  Total: 6306 pages (24.63 MB)
➜  ndk_template git:(master) ✗ adb shell /data/local/tmp/file_mem_stat 7181
  Present: 6269 pages (24.49 MB)
  Absent: 708742 pages (2768.52 MB)

  FilePage: 5 pages (0.02 MB)
    shared: 0 pages (0.00 MB)
    private: 5 pages (0.02 MB)
    dirty: 0 pages (0.00 MB)
    clean: 5 pages (0.02 MB)
    private & clean: 5 pages (0.02 MB)
  NonFilePage: 6264 pages (24.47 MB)
Private File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Shared File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Anonymous Pages:
  Total: 6264 pages (24.47 MB)
Private File + Anonymous Total:
  Total: 6264 pages (24.47 MB)
➜  ndk_template git:(master) ✗ adb shell ps -ef | grep tencent
u0_a172       7181  1524 0 19:47:29 ?     00:00:01 com.tencent.soter.soterserver
u10_a302     16080  1524 0 19:48:31 ?     00:03:49 com.tencent.mobileqq:MSF
u10_a309     17237  1524 1 16:20:49 ?     00:01:10 com.tencent.mm:appbrand1
u10_a309     18194  1524 0 19:48:41 ?     00:03:46 com.tencent.mm:push
u10_a309     21857  1524 2 17:45:03 ?     00:00:06 com.tencent.mm:appbrand0
u10_i9033    22950  1524 3 17:45:50 ?     00:00:09 com.tencent.mm:xweb_sandboxed_process_0:com.tencent.xweb.pinus.sdk.process.SandboxedProcessService
u10_a309     22971  1524 0 17:45:50 ?     00:00:01 com.tencent.mm:xweb_privileged_process_0
u10_a309     23765  1524 1 23:06:08 ?     00:15:50 com.tencent.mm
u10_a309     27571  1524 19 17:50:22 ?    00:00:02 com.tencent.mm:support
u10_a302     29021  1524 0 22:42:00 ?     00:02:47 com.tencent.mobileqq
u10_a172     30085  1524 0 16:30:38 ?     00:00:00 com.tencent.soter.soterserver
➜  ndk_template git:(master) ✗ adb shell /data/local/tmp/file_mem_stat 22950
  Present: 42978 pages (167.88 MB)
  Absent: 64152924 pages (250597.36 MB)

  FilePage: 34163 pages (133.45 MB)
    shared: 0 pages (0.00 MB)
    private: 34163 pages (133.45 MB)
    dirty: 0 pages (0.00 MB)
    clean: 34163 pages (133.45 MB)
    private & clean: 34163 pages (133.45 MB)
  NonFilePage: 8815 pages (34.43 MB)
Private File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Shared File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Anonymous Pages:
  Total: 8815 pages (34.43 MB)
Private File + Anonymous Total:
  Total: 8815 pages (34.43 MB)
➜  ndk_template git:(master) ✗ adb shell /data/local/tmp/file_mem_stat 22971
  Present: 32455 pages (126.78 MB)
  Absent: 5481317 pages (21411.39 MB)

  FilePage: 10026 pages (39.16 MB)
    shared: 275 pages (1.07 MB)
    private: 9751 pages (38.09 MB)
    dirty: 0 pages (0.00 MB)
    clean: 10026 pages (39.16 MB)
    private & clean: 9751 pages (38.09 MB)
  NonFilePage: 22429 pages (87.61 MB)
Private File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Shared File Pages:
  Dirty: 0 pages (0.00 MB)
  Clean: 0 pages (0.00 MB)
Anonymous Pages:
  Total: 22429 pages (87.61 MB)
Private File + Anonymous Total:
  Total: 22429 pages (87.61 MB)