虚拟内存原理

简介: 虚拟内存原理

局部性原理

计算机组成原理里我们可以知道cache掉入的数据都是连续的

我们可以看下面的例子,data创建的数组,因为我们要读入的是这个数组所以调入的是这一段内存的内容就大概率不会miss

但是我们要知道有些程序的代码被执行的几率是很小的,我们要让大概率被执行的代码引用的空间落入cache,其实科学家研究过,一个程序其实只有一部分局部代码在运行时会被访问,并非所有代码都需要被执行。

这个就叫做局部性原理

大部分程序都是满足此原理

时间局部性有些变量会被重复访问

空间局部性比如a[i]=b[i]

修改缓存的数据

这里叫做脏区,大家可以自行百度一下,这个是计组的基础,其实就是修改cache然后回写

swap space

其实就是磁盘与内存的缓存区域

这个缓存也是为了解决硬盘和内存运行速度不匹配的问题,且硬盘容量比内存要大得多

所以这个缓存区能解决硬盘速度太慢,内存条空间较小的问题,他们是互补(理论上内存无限大)

我们做一个总结

我们看图,越往左存储空间越小,速度越快,越往右存储空间越大,速度越满。右边的设备是左边设备的扩充,我们只需要把常用数据放入左边的设备。

这整个就是虚拟内存的结构

部分装入,虽然内存很小,但是互补之后,我们只需要把不常用的存在低速设备里,常用的放入高速设备里,这就理论上达到无限内存,我们编程就不用担心物理内存的限制。

demand paging

请求式页面调度

并非所有虚内存的空间都在内存中有物理位置(从硬盘掉入内存),因为逻辑上我们需要满足无限内存,但是如果访问到不常用的数据就需要从硬盘里调用数据

判断页表里的valid/invalid值是否有效

判断数据是否在内存驻留

如果数据没有驻留在内存就向硬盘去调度(需要查询硬盘里是否有该数据),最后整个过程叫做paging

如果没有驻留在内存就不会产生page fault,直接取内存驻留的数据,如果有page fault就需要从硬盘调用数据进入内存

上面整个请求调页对于虚拟内存来说可以扩大内存空间,但是这个机制是要访问内存和硬盘的所以调页时间肯定是要比正常时间要低很多

其实这里还有个问题,如果需要调页时发现内存空间满了,那么调页磁盘的空间无法进入内存空间,这里我们就需要解决这个问题

根据下面的图我们可以发现我们可以用置换来解决,也就是我们需要讲一块内存空间存入硬盘,然后再讲我们需要的硬盘数据存入内存,这个过程就叫做页面置换

但这里还有个问题,如果调页置换,我们需要考虑刚置换的内存数据,会否等下又要置换回来,如果多次这样时很浪费运行周期的。

这里我们讨论一些算法

fifo算法先进先出

我们将最先进入内存空间的数据置换

因为这个数据再内存中待的最久,所以一般都已执行完了

我们举个例子,这个例子里我们可以看到3 0和2 3这里再0和3刚被淘汰下次执行又页面置换了,后面几次调用又好几个都是这样

我们可以看到除了前三个强制页面置换,一共发生了十二次页面置换

最优算法

我们可以看到这个算法产生的置换更少,因为它是根据后面需要的资源去判断谁需要被置换

而且既然它叫做最优了,那么基本就是目前最优了

但这里有个致命缺陷,导致整个算法无法实现,我们前面就提到过,我们无法预测程序下一步需要什么

那么我们优化整个算法尽量逼近这个算法的实现逻辑,我们无法判断后面进程需要什么资源,那么我们就只能根据前面执行过的来判断

LRU算法

比fifo算法少了三次,比最优算法多了三次。

系统的抖动

在页面置换时请求调出去的内存可能下一步指令有需要调用,所以这里会产生大量的反复调用调出的动作,这个动作就叫做抖动

这里最后一句说了抖动还有一个特性,就是置换的时间远远大于调用此进程的时间,这个就叫做抖动。

抖动的原因

页框分配太少

并发进程过多(这里其实也是进程过多页框过少)

相关文章
|
机器学习/深度学习 存储 算法
NoProp:无需反向传播,基于去噪原理的非全局梯度传播神经网络训练,可大幅降低内存消耗
反向传播算法虽是深度学习基石,但面临内存消耗大和并行扩展受限的问题。近期,牛津大学等机构提出NoProp方法,通过扩散模型概念,将训练重塑为分层去噪任务,无需全局前向或反向传播。NoProp包含三种变体(DT、CT、FM),具备低内存占用与高效训练优势,在CIFAR-10等数据集上达到与传统方法相当的性能。其层间解耦特性支持分布式并行训练,为无梯度深度学习提供了新方向。
739 1
NoProp:无需反向传播,基于去噪原理的非全局梯度传播神经网络训练,可大幅降低内存消耗
|
12月前
|
存储 缓存 Java
【高薪程序员必看】万字长文拆解Java并发编程!(5):深入理解JMM:Java内存模型的三大特性与volatile底层原理
JMM,Java Memory Model,Java内存模型,定义了主内存,工作内存,确保Java在不同平台上的正确运行主内存Main Memory:所有线程共享的内存区域,所有的变量都存储在主存中工作内存Working Memory:每个线程拥有自己的工作内存,用于保存变量的副本.线程执行过程中先将主内存中的变量读到工作内存中,对变量进行操作之后再将变量写入主内存,jvm概念说明主内存所有线程共享的内存区域,存储原始变量(堆内存中的对象实例和静态变量)工作内存。
347 0
|
算法 JavaScript 前端开发
新生代和老生代内存划分的原理是什么?
【10月更文挑战第29天】新生代和老生代内存划分是JavaScript引擎为了更高效地管理内存、提高垃圾回收效率而采用的一种重要策略,它充分考虑了不同类型对象的生命周期和内存使用特点,通过不同的垃圾回收算法和晋升机制,实现了对内存的有效管理和优化。
【C++】深入解析C/C++内存管理:new与delete的使用及原理(二)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
277 4
|
编译器 C++ 开发者
【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
343 3
|
存储 C语言 C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(一)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
345 3
|
监控 算法 Java
Java内存管理:垃圾收集器的工作原理与调优实践
在Java的世界里,内存管理是一块神秘的领域。它像是一位默默无闻的守护者,确保程序顺畅运行而不被无用对象所困扰。本文将带你一探究竟,了解垃圾收集器如何在后台无声地工作,以及如何通过调优来提升系统性能。让我们一起走进Java内存管理的迷宫,寻找提高应用性能的秘诀。
|
安全 C语言 C++
彻底摘明白 C++ 的动态内存分配原理
大家好,我是V哥。C++的动态内存分配允许程序在运行时请求和释放内存,主要通过`new`/`delete`(用于对象)及`malloc`/`calloc`/`realloc`/`free`(继承自C语言)实现。`new`分配并初始化对象内存,`delete`释放并调用析构函数;而`malloc`等函数仅处理裸内存,不涉及构造与析构。掌握这些可有效管理内存,避免泄漏和悬空指针问题。智能指针如`std::unique_ptr`和`std::shared_ptr`能自动管理内存,确保异常安全。关注威哥爱编程,了解更多全栈开发技巧。 先赞再看后评论,腰缠万贯财进门。
606 0
|
监控 算法 Java
深入理解Java中的垃圾回收机制在Java编程中,垃圾回收(Garbage Collection, GC)是一个核心概念,它自动管理内存,帮助开发者避免内存泄漏和溢出问题。本文将探讨Java中的垃圾回收机制,包括其基本原理、不同类型的垃圾收集器以及如何调优垃圾回收性能。通过深入浅出的方式,让读者对Java的垃圾回收有一个全面的认识。
本文详细介绍了Java中的垃圾回收机制,从基本原理到不同类型垃圾收集器的工作原理,再到实际调优策略。通过通俗易懂的语言和条理清晰的解释,帮助读者更好地理解和应用Java的垃圾回收技术,从而编写出更高效、稳定的Java应用程序。
|
缓存 Java 编译器
Go 中的内存布局和分配原理
Go 中的内存布局和分配原理