最近看深入理解计算机系统内存章节部分,看完之后想着实操一下,于是从最熟悉的 macOS/iOS 下手,看一下进程的虚拟内存区域是如何分布的。
直接上代码
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
struct task_basic_info task_basic_info;
mach_msg_type_number_t size = sizeof(task_basic_info);
//1. 获取task_info
kern_return_t kerr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&task_basic_info, &size);
if (kerr == KERN_SUCCESS) {
NSLog(@"%lu",task_basic_info.resident_size);
NSLog(@"%lu",task_basic_info.virtual_size);
} else {
printf(0);
}
kern_return_t ret;
task_t task;
unsigned int depth = 0;
uint64 addr = 0;
int count;
//1. 拿到当前的任务 #需要通过进程 id 获取
//2. 获取地址 1 所在的 VMA
//3. 递归获取进程的 VMA
int pid = [[NSProcessInfo processInfo] processIdentifier];
printf("进程id %d\n", pid);
uint64 target_addr = 1;
vm_size_t vm_size = 0;
vm_region_submap_info_data_64_t info;
mach_msg_type_number_t info_count = VM_REGION_SUBMAP_INFO_COUNT_64;
mach_port_t object_name;
ret = task_for_pid (mach_task_self(), pid, &task);
ret = vm_region_64(task, &target_addr, &vm_size, VM_REGION_BASIC_INFO_64, &info, &info_count, &object_name);
while (ret == KERN_SUCCESS) {
printf("vma address area [%p-%p] size %d\n ",target_addr, target_addr+vm_size, vm_size);
target_addr = target_addr + vm_size;
ret = vm_region_64(task, &target_addr, &vm_size, VM_REGION_BASIC_INFO_64, &info, &info_count, &object_name);
}
if (ret != KERN_SUCCESS)
return 0;
[[NSRunLoop currentRunLoop] run];
}
return 0;
}
对应命令
vmmap [processid] —-verbose
参考地址:
- 深入解析 MAC OS X & IOS 操作系统 - 11.1 调度原语
- 深入解析 MAC OS X & IOS 操作系统 - 12.1 虚拟内存架构