第八十八天学习记录:对内存和虚拟内存的一些疑问

最近在看一本名为《程序员的自我修养-链接、装载与库》的书。
为了看懂这本书,甚至还学起了《计算机硬件基础》
然而看这些内容一直是看得我云里雾里……走马观花的浏览以至于大部分内容都不能理解。
也可能是我知道自己的重心不在这一块,毕竟这些枯燥的东西加上没有通过系统性学习,光靠自学是难以理解的。不过,我仍然对其中很多方面心存好奇,比如原来程序可以不通过main函数作为开始的接口,并且可以不通过<stdio.h>在终端输出内容……
以下是我和ChatAI关于物理内存和虚拟内存的提问,以便我后面重读这本书的时候可以再次查看这次聊天记录……也许专业人士看到这些提问会觉得有些“奇怪”。就像我现在看我之前不理解指针时和ChatAI提出的问题一样。但或多或少还是有帮助的。

问:
一个程序的虚拟内存是否可以这样理解?当程序运行起来之后,会根据程序本身有一个虚拟地址。然后将这些虚拟地址对应到物理内存的地址。因此当程序虚拟地址大于物理地址时,操作系统也可以根据正在运行的模块选择对应的虚拟地址?
答:
是的,你的理解基本正确。我们可以将程序的虚拟内存理解为一种抽象概念,它提供给程序一个连续的、私有的地址空间,程序可以在这个地址空间中执行操作。实际上,这个虚拟地址空间并没有直接映射到物理内存的地址,而是通过操作系统的内存管理单元进行映射。
在运行程序时,每个程序都有自己的虚拟地址空间,程序中的每个变量、对象或指令都使用虚拟地址来访问。操作系统负责将程序的虚拟地址映射到物理内存的地址,这样程序就可以执行读写操作,而不需要了解物理内存的实际情况。
当程序的虚拟地址大于物理地址时,操作系统会根据当前运行的模块选择对应的虚拟地址。这通常是通过内存分页技术来实现的,将虚拟地址空间划分为固定大小的页,每个页映射到物理内存的一页。当程序访问一个虚拟地址时,操作系统会检查该地址所在的页是否已经加载到物理内存中,如果没有,则触发页错误,操作系统会将相关的物理页加载到内存中,然后重新执行相关指令,使程序可以顺利执行。
总之,虚拟内存的概念使得程序可以在一个连续的地址空间中运行,而不需要关心物理内存的具体情况,这为操作系统提供了更灵活和高效的内存管理方式。

问:
页错误用户能够感知到吗?当页错误过多时是不是就会产生程序卡顿的情况?
答:
一般情况下,用户通常无法直接感知到页错误的发生。页错误是发生在操作系统内部的一种异常情况,它会导致操作系统需要从磁盘加载缺失的物理页到内存中,这个过程对于用户是透明的。
然而,当程序经常发生页面错误,导致频繁的磁盘访问和内存加载时,可能会对程序的性能产生影响,使程序出现卡顿的情况。这是因为磁盘访问的速度相对较慢,而加载物理页到内存需要一定的时间,这会导致程序的执行时间延长。
当程序发生过多的页错误时,通常有两种可能的原因:一是程序访问的数据或指令集不连续,导致内存中的页面经常无法满足连续访问的需求;二是程序的工作集大小超过了内存容量,导致频繁的页面置换。在这两种情况下,频繁的页错误将会带来性能下降和卡顿的问题。
为了尽可能减少页错误和提高性能,操作系统通常会采取一些策略,如使用预先加载机制、页面置换算法、调整页面大小等,以优化内存管理和降低页错误的频率。程序开发者也可以通过优化程序的数据访问模式和减少内存占用来减少页错误的发生。

问:
一个操作系统上的所有应用程序是不是不能超过虚拟内存?
答:
在理论上,一个操作系统上的所有应用程序的虚拟内存总和可以超过物理内存的大小,这就是虚拟内存的作用之一。虚拟内存可以为每个应用程序提供一个连续的、私有的地址空间,使得每个应用程序都可以独立使用一定大小的地址空间,而不需要关心实际的物理内存大小。
当应用程序请求使用虚拟地址空间中的某个地址时,操作系统会将相应的物理页加载到内存中。如果物理内存不足以容纳所有被加载的物理页,则操作系统会使用页面置换算法将一部分物理内存中的页换出到磁盘上,腾出空间给即将加载的页使用。
虚拟内存的优势是可以将内存资源动态分配给应用程序,允许同时运行多个应用程序,而不需要显式地限制每个应用程序的虚拟内存大小为物理内存的大小。然而,在实际情况中,由于操作系统本身也需要占用一部分内存,还有其他系统和进程的开销,所以操作系统上的所有应用程序的虚拟内存总量是受限的,不能无限制地超过物理内存和操作系统的资源限制。
因此,尽管虚拟内存可以提供给每个应用程序一个较大的地址空间,但在实际使用中仍然需要考虑物理内存和操作系统资源的限制。同时,为了保证系统性能和稳定性,操作系统可以采取一些管理策略,例如限制每个应用程序的虚拟内存大小,对应用程序进行优先级调度等。

问:
32位系统的4G寻址空间是不是就是指的虚拟空间最大值。
答:
是的,对于32位系统来说,通常指的是寻址空间为4GB(2e32)。其中,1GB被保留给操作系统使用,剩下的3GB(2e30)可以被应用程序使用。这3GB的空间被称为用户空间,用来存放应用程序的代码、数据和堆栈等。
在32位系统中,一个应用程序可以拥有最多4GB的虚拟地址空间,但实际上并不是所有的虚拟地址空间都用于访问物理内存。其中的一部分地址空间被保留给操作系统和其他系统资源。通常,操作系统会将这些虚拟地址空间划分为不同的段,用于存放操作系统的内核、驱动程序和其他系统资源。
因此,对于一个32位应用程序来说,它的虚拟地址空间最大值是4GB,但实际可供应用程序使用的虚拟地址空间大小要小于4GB,取决于操作系统的具体设计和配置。在一些情况下,应用程序的虚拟地址空间可能会受到其他限制,例如特定应用程序的内存分配策略、编译器的限制等。

问:
假如,32位的操作系统装了8G的物理内存。运行了几个大型3D游戏,这些游戏的内存总和为7G,那么这样的情况系统能够承受吗?
答:
在32位操作系统下,每个进程默认的地址空间大小通常是4GB,即使系统装有8GB的物理内存。无论物理内存的大小如何,单个进程能够使用的虚拟地址空间限制在4GB范围内。
如果你运行了几个大型的3D游戏,它们的内存总和达到了7GB,那么在32位操作系统下,这些进程的内存需求超过了单个进程可用的虚拟地址空间大小。这意味着至少有一个或多个游戏无法完全加载到内存中。
在这种情况下,操作系统通常采用一些策略来管理内存。例如,它可能使用虚拟内存机制,将一部分进程的内存数据临时存储在磁盘上,这样即使物理内存不足,也可以继续运行程序。但这会导致磁盘交换(paging)频繁发生,性能可能会受到一定影响,包括加载时间延迟和响应速度下降。
总的来说,尽管物理内存配置为8GB,但在32位操作系统中,单个进程可用的虚拟地址空间限制为4GB,无法直接利用全部8GB的物理内存。对于运行多个大型3D游戏的情况,可能会面临内存不足的问题,需要注意内存管理和资源分配,以避免系统性能问题。为了更好地支持大内存需求,建议使用64位操作系统,以更充分地利用8GB物理内存及以上。

问:
如果在32位系统上允许一个内存5G的特大游戏,选择4G物理内存和8G物理内存对游戏性能上有无区别?
答:
在32位操作系统下,单个进程的虚拟地址空间限制为4GB,因此无论物理内存的大小是4GB还是8GB,单个进程最多只能使用4GB的虚拟地址空间。
如果你运行一个内存需求为5GB的特大游戏,无论你的物理内存配置为4GB还是8GB,这个游戏都将无法完整加载到内存中,因为它超过了单个进程所允许的地址空间大小。
当物理内存无法完全容纳游戏所需的全部内存时,操作系统通常会采取虚拟内存技术,将不常用的内存数据临时存储到硬盘上,这样可以继续运行程序,但会导致性能下降。这种频繁的磁盘交换可能会增加访问延迟,导致游戏运行速度变慢,加载时间延长,帧率下降等。
因此,无论物理内存配置为4GB还是8GB,在32位操作系统下运行一个内存需求超过4GB的特大游戏时,它的性能都会受到限制,可能会出现较长的加载时间、较低的帧率以及潜在的卡顿等问题。要更好地支持运行大型游戏,建议使用64位操作系统和更大的物理内存配置,以充分利用内存资源并提升游戏性能。

问:
我不是很理解32位系统的寻址方式。这里所说的4G寻址范围指的是最大限制,还是说物理限制?比如有8G的物理内存,那么32位系统仍然可以调用所有物理地址,还是说它只能调用固定的4G物理地址而其他4G永远调用不到?
答:
对于32位系统,4G寻址范围指的是最大限制,也就是说它只能调用固定的4GB物理地址空间,而其他4GB的物理地址空间无法直接被32位系统调用。
在32位操作系统中,寻址空间是通过32位的寻址方式实现的。这意味着系统最多能够寻址2^32个不同的地址,也就是4GB的地址空间范围。
物理内存的大小不会直接影响32位系统的寻址范围,因为物理内存的大小可以超过这个32位寻址空间的范围。尽管系统实际上可以配置8GB物理内存,但是32位系统只能够直接寻址到其中的前4GB,而超出该范围的物理内存将无法直接被32位系统调用和利用。
对于超出4GB范围的物理内存,32位系统可以通过使用物理地址扩展技术(PAE,Physical Address Extension)来间接寻址,但由于寻址方式的限制,单个32位进程仍然只能访问到4GB的虚拟地址空间。因此,即使系统具备8GB的物理内存,但对于单个进程来说,它仍然只能访问到其中的4GB。
总而言之,32位系统的最大寻址范围是4GB,物理内存的大小可以超过这个范围,但对于单个进程来说,它只能直接访问到4GB的虚拟地址空间和其中对应的物理地址空间。超出这个范围的物理内存可以通过技术手段间接访问,但存在一定的限制和性能损失。因此,为了更好地支持大内存需求,建议使用64位操作系统。

问:
这里提到单个进程的最大虚拟空间是4G,那是不是意味着如果有10个虚拟空间是2G的程序同时允许,他们单个进程都没有超过4G,在物理内存允许的情况下(大于20G),这10个程序也可以很流畅的运行?
答:
对的,在32位操作系统下,单个进程的虚拟地址空间限制为4GB。如果有10个虚拟空间是2GB的程序同时运行,并且每个程序的内存需求都没有超过4GB,在物理内存足够的情况下(大于20GB),这10个程序可以很流畅地运行。
由于每个程序的内存需求都小于4GB,它们可以完全加载到单个进程的虚拟地址空间中。而在物理内存足够的情况下,这些程序也可以顺利地分配到各自的物理内存空间。
当程序运行时,操作系统会负责将程序的虚拟地址映射到物理地址,并通过内存管理机制来管理和分配物理内存资源。如果物理内存足够,这些程序可以同时运行,并且由于各自独立的虚拟地址空间,它们之间不会相互干扰。
需要注意的是,尽管单个进程的虚拟地址空间限制为4GB,但这并不意味着整个系统的物理内存也受到同样的限制。在具备大于4GB物理内存的情况下,操作系统可以通过内存分页等技术来支持多个进程同时运行,并分配适当的物理内存给它们。
因此,在给定足够物理内存的情况下,如果有多个内存需求小于4GB的程序同时运行,它们可以很流畅地运行,而不会受到单个进程虚拟地址空间的限制。当然,系统的整体性能还会受到其他因素的影响,例如处理器性能、磁盘速度等。

猜你喜欢

转载自blog.csdn.net/weixin_45694614/article/details/131445201