本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一、前言
在上文《Java并发编程:虚拟内存详解(一)》,我们了解了虚拟内存的定义,以及为什么需要虚拟内存。本文将接下来为大家讲解虚拟内存的实现。
二、虚拟内存的优势
在传统存储管理
中,应用程序的内存数据是直接全部写入到内存中的,而且要等到应用程序执行结束以后,才会将内存释放出来。这样会导致内存空间非常容易满(毕竟都是将应用程序的内存全量写入),而且,当内存满以后,其它应用程序只能进行等待,直到当前占用内存的应用程序结束,释放出内存空间了,才能运行。这种模式下,内存的利用率非常低
。
而在虚拟内存
中,采用的是基于局部性原理
的数据块模式。当应用程序启动时,只会将一部分数据加载到虚拟内存中,当运行过程中需要用到其它数据时,再使用缺页中断
的方式,将之加载到内存。这种模式下,内存中存储的是当前正在使用的数据,而当前不需要或者不常用的数据,会被放到外存(例如磁盘)中,大大的提高了内存的利用率。
局部性原理
在之前写的文章(《Java并发编程:硬件上的并发上篇》)中有做过解释,感兴趣的朋友可以去这篇文章看下。
三、虚拟内存调度
从上一节可知,虚拟内存
的数据存储是以块
为单位的,而不同的操作系统,对这块功能也是有不同的实现,基本上可以分为以下三种:
页式调度
页式调度是将虚拟内存和物理内存都分配成固定大小
的页。然后通过页表
,将虚拟内存与物理内存对应起来。此调度模式的优点是模式简单,缺点是应用程序使用的内存是离散分布的,不利于应用程序数据保护。除此之外,此模式也容易出现页内空间碎片
。
Linux用的就是此模式。
段式调度
段式调度不同于页式调度,段的长度不是固定的,可以根据应用程序的需要动态分配。此模式下,虚拟内存与物理内存通过段表
进行关联。此模式的好处是应用程序的数据都在一起,有利于应用程序的数据保护,而且不会造成页内空间碎片。缺点是内存动态分配,容易产生外空间碎片
,调度逻辑也会相对复杂。
段页式调度
段页式调度将物理内存分配成固定大小
的页,然后虚拟内存则使用分段的方式去给应用程序分配内存,再在段内,使用页的方式进行划分。此模式下,操作系统需要通过段表
和页表
的配合使用,才能跟物理内存对应起来。
段页式调度融合了页式调度和段式调度的优点,但是缺点也非常明显,就是增加了硬件成本,也增加了系统的复杂度。
四、后言
既然看到这里了,感觉有所收获的朋友,不妨来个大大的点赞吧~~~