madvise

 

void MemMap::MadviseDontNeedAndZero() {
  if (base_begin_ != nullptr || base_size_ != 0) {
    if (!kMadviseZeroes) {
      memset(base_begin_, 0, base_size_);
    }
    int result = madvise(base_begin_, base_size_, MADV_DONTNEED);
    if (result == -1) {
      PLOG(WARNING) << "madvise failed";
    }
  }
}

 在低内存模式中,Dalvik虚拟机假设对象不会马上就使用分配到的内存,因此,它就通过系统接口madvice和MADV_DONTNEED标志告诉内核,刚刚分配出去的内存在近期内不会使用,内核可以该内存对应的物理页回收。当分配出去的内存被使用时,内核就会重新给它映射物理页,这样就可以做按需分配物理内存,适合在内存小的设备上运行。这里有三点需要注意。

 

 

madvise 给关于使用内存
int madvise(void *addr 、长度 size_t , int 建议);


在madvise()系统调用内核中关于如何处理分页 input/output 判断地址 addr 处开始的区域的地址和大小长度的字节.它允许一个 application 来告诉内核如何它需要使用某些映射或共享内存区域,使内核可以选择适当的预读和缓存技术.此调用不会影响应用程序的语义的(除在 madv_dontneed 大小写),但可以配置它的性能.要忽略建议的内核是免费的.

在处理,建议参数可以是

madv_normal
    特殊处理.这是默认的.
madv_random
    类以随机顺序引用页.(因此,预读比通常会很有用 .)
madv_sequential
    类按顺序依次引用页.(因此,在给定的页面区域可以 aggressively 预读.和可能释放后 .)
madv_willneed
    预计在不久的将来访问(因此,可能最好以阅读一些页面 .)
madv_dontneed
    不要期待在不久的将来访问(用的时间.用给定的范围后,使内核可以释放与它关联的资源.)在此范围内的页的后续访问都将成功,但从基础会在重新装入存储器内容的映射文件(看到mmap(2))在没有基本映射的页面请求或零填充
madv_remove(因为已经为)
    释放给定的范围和与其相关联的备份存储.目前,只有 shmfs/tmpfs 支持此;其他文件系统的错误返回 enosys .
madv_dontfork(因为已经为)
    不要使在此范围内的页子之后fork(2).这是有用的,防止写上复制语义更改页的物理位置.(s)如果写入之后fork(2).(这样的页面指令导致硬件 dmas 至页面(s).)
madv_dofork(因为已经为)
    撤消 madv_dontfork ,还原默认行为,即映射继承在 fork 的效果(2).
madv_hwpoison(因为 linux 2.6.32)
    当一个网页以及其句柄可以像内存硬件的损坏.此操作仅对于特权(cap_sys_admin)进程.此操作可能导致接收日志和页面调用进程没有定义.此功能仅用于测试的内存错误处理代码;它仅在配置为使用 config_memory_failure .
madv_soft_offline(因为 linux 2.6.33)
    区域中的软脱机页的地址和长度.指定区域中的每一页的内存是保留(即,当访问,都将看到相同的内容,但在一个新的物理页面框架),和原始网页 offlined(例如,不再使用,超出正常的内存管理).以下是 madv_soft_offline 隐身的效果来(即,不能更改语义)调用进程.此功能仅用于测试的内存错误处理代码;它仅在配置为使用 config_memory_failure .
madv_mergeable(因为 linux 2.6.32)
    启用内核 samepage 合并(内存膨胀和ksm)指定的范围中的页地址和长度.内核经常能够扫描用户的内存已经被标为 mergeable ,具有相同内容的页.这些是用单个写保护页(可自动复制如果进程以后想要更新的页的内容).ksm操作合并私有匿名页面(看到mmap(2)).用于生成 实例数目相同的内存膨胀和 ksm 特征数据(例如,诸如 kvm 的虚拟系统).它可以消耗大量的处理能力;请谨慎使用.查看内核源文件 documentation/vm/ksm.txt 有关的细节.与 config_ksm madv_mergeable 和 madv_unmergeable 操作只能在内核被配置.
madv_unmergeable(因为 linux 2.6.32)
    撤消先前的效果 madv_mergeable 操作在指定的地址范围;内存膨胀和 ksm unmerges 任何页面时,合并在地址范围指定的地址和长度.
madv_hugepage(因为 linux 2.6.38)
    启用透明极大的页(thp)指定的区域中的网页地址和长度.目前,透明向来仅使用私有匿名页面的页面(看到mmap(2)).下面的例子将定期扫 描区域被标为候选页面来替换它们,极大的网页了.内核也将分配大页面直接当分解的庞大与页大小(看到posix_memalign(2)).此功能主要是 以使用大型映射访问大型和数据的内存区域的时间(例如,诸如 qemu 虚拟系统).它可以非常轻松地浪费内存(例如, 2mb 曾访问映射只1个字节将导致有线的 2mb 内存的一个为 4kb 页面).查看内核源文件 documentation/vm/transhuge.txt 有关的细节.以下 madv_hugepage 和 madv_nohugepage 操作 如果内核配置为使用 config_transparent_hugepage 可用.
madv_nohugepage(因为 linux 2.6.38)
    在指定的地址范围以确保内存地址和长度将不会被折叠到极大的页.

返回值

在成功madvise()返回零.上的错误,则返回-1, errno 提到它.

posted @ 2016-04-01 19:50  牧 天  阅读(6206)  评论(0编辑  收藏  举报