yongyuan.jiang 发表于 2013-1-15 02:59:29

jvm & memory (1) paging

本文出处:http://songsun.spaces.live.com/blog/cns!2DB8261011445D70!211.entry
 
 
近期看了一些有关JVM和内存的资料,为了避免遗忘,特在这里作一笔记。今天说说操作系统的虚拟内存先。http://songsun.spaces.live.com/rte/emoticons/lightbulb.gif

虚拟内存管理(VMM)是现在操作系统广泛采用的内存管理方式,为什么出现VMM了呢,当初主要是为了解决物理内存不足的问题,既然是不足,设计师们当然就想起来用硬盘空间来协力,使用诸如LRU(最近最少使用)之类的算法,把物理内存(Mainmemory)中不怎么使用的内容,转储到硬盘上以节省空间(给急需内存的程序使用),而转储到硬盘上的内容又被访问时,再转载回来(http://songsun.spaces.live.com/rte/emoticons/smile_sad.gif如果总是发生这样的事,系统地效能就大大折扣了,这也是好的算法应该避免的)。

题外话:虽说VMM的实现主要是操作系统的事,但早期没有可支持VMM管理的CPU诞生时,如Intel系列,在386以前,要纯粹依靠OS自身做VMM,不仅麻烦而且效率也很差。要知道VMM是1960年以前就有这概念了,早期的实现者(如果有的话)肯定很郁闷。

继续正题,怎么做到VMM的呢,首先要定义一个概念,叫做虚拟地址空间(virtual memory spaces),这个空间就是进程是装载和运行的容器,以win32为例,32位的虚拟地址空间(virtual memoryspaces)可以达到4GB那么大,这对于一般应用程序来说,几乎是富裕的太多了。这么大的空间,为了便于管理,首先按照特定粒度划分一个最小的基本单元,叫做页(Page),比如等于64kb吧,页有三类:Free,Reserved,Committed,Free的页对于进程来说,等于是不可用的,任何读写free页的行为都是极其无耻卑劣和下流的,要被OS严惩不贷(可以放心的是,你的Java程序不会发生这类行为,只有那些可以直接内存寻址的语言才可能发生);而Reserved的页是进程保留将来要使用的,这部分暂时还没有实际对应(物理内存或硬盘);Committed是OS已经提交给进程供其使用的,这部分虚拟内存可以由虚地址转换到实际的物理地址。

为什么要先说VMM呢,这和JVM有啥联系呢?这是因为JVM的堆(指Javaheap)内存是动态扩张的,但它又总是连续的(JVM为了便于垃圾清理),怎么做到这样呢?JVM会首先申请一大块内存作堆,而其中只有开始使用的部分是Committed的,剩余的都是Reserved的,随着扩张过程,逐步把Reserved的变成Committed。而当JVM发觉堆过大值得减小时,又会把尾部的一部分堆释放回Reserved状态。

访问虚拟空间的每个地址的内容时,首先会把这个虚拟地址转换成物理地址,转换过程一般由cpu自己来完成,很快&很准,所以你不用担心速度问题或者转换出错。每一页的基址转换好了,页内的地址用过偏移地址访问即可,几乎没有转换的开销。所以把这个转换的过程叫做Paging,如果页是Free的,CPU会发生accessviolation,二话不说就直接转去执行寻址违例的处理过程,所以windows蓝屏会来的那么突然啊!如果页是Resreved或者页被交换到硬盘上,这时不能直接在物理内存中找到对应,那么发生Pagefault,CPU转去执行相应例程做补救,把页交换回来,过程虽然费事,但进程自己什么也感觉不到(用户可就不能幸免了)。这些关键功能都是现代CPU直接具备的,OS只要把相应处理例程准备好就OK。

附一张切来的paging示意图,点击可看大图。

到此,一个庞大的虚拟地址空间就完全为进程准备好了,但别以为应用程序能够使用它的全部,因为操作系统及接口也是应用程序赖以生存的必不可少的,它们往往也预先落户在进程的虚拟地址空间里。

VMM还促使动态链接库(dll)技术(这个和jni有点联系)大行其道,这是别话了。
页: [1]
查看完整版本: jvm & memory (1) paging