在Android上,为什么ps命令在应用程序未分配任何内容时显示高虚拟内存?

Dav*_*one 0 android

我在Android上使用ps命令来确定应用程序使用的内存(只是一个普通的基于Java的应用程序).我有一个测试应用程序,它分配尽可能多的内存(通过重复创建1兆字节的数组,并将它们添加到List中,这样它们就不会超出引用,直到分配失败).

ps为测试应用程序显示的"RSS"(Resident Set Size)列似乎是明智的 - 当应用程序启动时它很低,然后在我分配了一堆内存后它会高得多.但VSIZE/VSS列开始时非常高,并且不会更改.在Android上由ps报告的VSIZE/VSS列的含义是什么?

在明确分配任何内存之前,这是我的测试应用程序的ps输出.单位是千字节

USER     PID   PPID  VSIZE  RSS     WCHAN    PC         NAME
u0_a55    2271  91    468664 30008 ffffffff 00000000 S com.dave.quicktest
Run Code Online (Sandbox Code Playgroud)

这是在我分配内存直到筋疲力尽之后:

USER     PID   PPID  VSIZE  RSS     WCHAN    PC         NAME
u0_a55    2271  91    468692 287232 ffffffff 00000000 S com.dave.quicktest
Run Code Online (Sandbox Code Playgroud)

从30mb到287mb时的RSS,差异大致与分配的内存量相匹配.但VSIZE一开始就是468mb,而且变化不大.为什么?

另外,我可以确认Android OS实际上没有使用页面文件/交换空间吗?我不怀疑有可能构建/配置它这样做,但在正常的库存操作系统构建中,它是否会对存储进行VM分页?

多谢你们!

Chr*_*ton 5

Android应用程序不是通常的fork()启动,而exec()意味着干净的过程映像.

相反,一个名为zygote的已经运行的程序被指示通过更改为应用程序用户标识并加载构成特定应用程序的java(和可能是本机)代码库来分叉子项并使其专门化.

这种奇怪行为的原因是,zygote已经"加载"了大多数系统提供的java和本机库,Android应用程序可能会想要使用它们.由于这些主要包含只读代码页,一个子进程继承访问它们几乎是免费的 - 有没有必要到一个新的副本加载到内存中的每个程序.并且只有在实际写入时才会复制正在运行的实例可能需要的少数关联数据页.因此,这是一种非常有效的方案,可最大限度地减少资源受限多处理系统上的重复内存使用.

但是,由于所有这些库(无论是否需要)都映射到每个应用程序的地址空间并且理论上可用,因此每个应用程序的虚拟内存大小将显得相当高.