在链接时重定位期间,链接器将运行时地址分配给生成的可执行文件中的每个节和每个符号
这些运行时地址是否对应于虚拟地址?
如果生成可执行文件的系统不使用虚拟内存怎么办?
接下来,如果不使用虚拟内存,则应用程序的地址空间将限制为加载时重定位后操作系统为其分配的物理地址空间
我认为,确实如此:如果包含所请求的物理地址的物理页尚未存储在 RAM 中,则应该发生页错误,这是由操作系统页错误处理程序提供服务的
我这样问是因为分页总是与虚拟内存一起提到,但似乎分页不需要虚拟内存的存在
谢谢
paging operating-system dynamic-linking virtual-memory static-linking
考虑以下 CPU 指令,该指令获取地址 16777386(十进制)处的内存并将其存储在寄存器 1 中:
Move &0x010000AA, R1
传统上,程序在编译时被翻译为汇编(机器代码)。(让我们忽略更复杂的现代系统,例如抖动)。
但是,如果这个地址分配是在编译时静态完成的,操作系统如何确保两个进程不使用相同的内存?(例如,如果您同时运行相同的编译程序两次)。
问题:
程序如何以及何时分配其内存地址?
虚拟内存:
我了解大多数(如果不是全部)现代系统在硬件中使用内存管理单元来允许使用虚拟内存。地址空间的前几个八位字节用于引用哪个页面。如果每个进程使用不同的页面,这将允许内存保护。但是,如果这就是执行内存保护的方式,那么最初的问题仍然存在,只是这次如何分配页号?
编辑:
中央处理器:
一种可能性是 CPU 可以通过强制操作系统在执行基于内存的指令之前分配进程 ID 来处理内存保护。然而,这只是猜测,需要 CPU 架构的硬件支持,我不确定 RISC ISA 的设计目的是什么。
mmapDarwin 的联机帮助页指定,为了与mmap超级页面(Darwin 相当于 Linux 的大页面)一起使用,VM_FLAGS_SUPERPAGE_SIZE_*应该使用标志。
我尝试在 Rust 中使用此功能,但在 Darwin 的 Rust libc 版本( i686、x86_64 )中找不到这些常量。
我正在运行一个 5k loc Express 应用程序,其中包含许多其他依赖项,包括 Express。该应用程序称它需要大约 60 MB RAM RSS。但是,当查看我的 Linux 机器上的实际 RAM 使用情况时,top我发现它使用了约 1200 MB VIRT 内存,而仅占用了约 60 MB RES (RSS) 内存。
然后我编写了一个简单的test.js脚本来隔离案例:
setInterval(() => {
console.log(JSON.stringify(process.memoryUsage()));
} , 1000);
Run Code Online (Sandbox Code Playgroud)
并开始使用:node test.js
它告诉我它使用了大约 30 MB RAM:
{"rss":30097408,"heapTotal":6537216,"heapUsed":3829224,"external":8272}
Run Code Online (Sandbox Code Playgroud)
再次查看top命令中的内存,它显示 RES 为 30 MB,但 VIRT 使用量约为 470 MB。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
8498 ted 20 0 485948 29928 23540 S 0,3 0,8 0:00.44 node
Run Code Online (Sandbox Code Playgroud)
NodeJS 这样看起来并不轻量。 …
假设一个简单的 hello world in C,编译gcc -c为目标文件并反汇编为objdump如下所示:
_main:
0: 55 pushq %rbp
1: 48 89 e5 movq %rsp, %rbp
4: c7 45 fc 00 00 00 00 movl $0, -4(%rbp)
b: c7 45 f8 05 00 00 00 movl $5, -8(%rbp)
12: 8b 05 00 00 00 00 movl (%rip), %eax
Run Code Online (Sandbox Code Playgroud)
如您所见,内存地址是0, 1, 4, ..等等。它们不是实际地址。
链接目标文件并反汇编它看起来像这样:
_main:
100000f90: 55 pushq %rbp
100000f91: 48 89 e5 movq %rsp, %rbp
100000f94: c7 45 fc 00 00 …Run Code Online (Sandbox Code Playgroud) 我正在升级一个 .NET 库以支持 64 位。该库直接在 Windows 上的其他进程的内存中执行各种操作。我必须在两种类型IntPtr(最大正值 7FFF'FFFF'FFFF'FFFF)或UIntPtr(最大正值 FFFF'FFFF'FFFF'FFFF)之间进行选择来处理我的内存指针。网上有很多关于这两者的信息。IntPtr似乎是事实上的约定选择,因为它符合 CLS 并且大多数 .NET API 都依赖于它(参考Marshal来自InteropServices)。
我决定打开一个 64 位进程并检查分配的内存区域,以及进程中加载的模块,以查看使用UIntPtr(addresses > 7FFF'FFFF'FFFF'FFFF)支持无符号指针是否有价值。如下面的屏幕截图所示,似乎内存地址不会加载符号,也不会分配超过 7FFF'FFFF'FFFF 的内存。这样做有什么具体原因吗?在某些情况下,Windows 可以根据该值分配内存区域吗?
我正在调查一个进程的内存使用情况,该进程(意外地)保留了 TB 的VIRT. 如果我执行pmap该过程,我可以看到一些强大的分配,例如:
00007f39ea671000 317288696K rw--- [ anon ]
Run Code Online (Sandbox Code Playgroud)
我正在strace跟踪所有与内存相关的系统调用并记录它们的跟踪跟踪,从而运行我的进程。
strace -o ~/strace.out -f -e trace=mremap,mmap,munmap,brk -k <command>
Run Code Online (Sandbox Code Playgroud)
我希望能够在 中找到这个分配strace.out,所以我 grep 它:
cat strace.out | grep -A10 7f39ea671000
Run Code Online (Sandbox Code Playgroud)
我只看到这个调用mmap:
106224 mmap(NULL, 201543680, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f39ea671000
> /usr/lib/x86_64-linux-gnu/libc-2.29.so(mmap64+0x22) [0xf5252]
> /usr/lib/x86_64-linux-gnu/libc-2.29.so(_IO_str_seekoff+0x2ff4) [0x84ab4]
> /usr/lib/x86_64-linux-gnu/libc-2.29.so(_IO_str_seekoff+0x3e0b) [0x858cb]
> /usr/lib/x86_64-linux-gnu/libc-2.29.so(__libc_malloc+0x22f) [0x869ff]
...
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?是否pmap显示了夸大的映射尺寸?或者我错过了一些系统调用?
通过运行一个简单的程序,less /proc/self/maps我发现大多数映射都以55and开头7F。我还注意到每当我调试任何二进制文件时都会使用这些范围。
此外,该评论在这里表明,内核的确有些范围的偏好。
这是为什么?上述范围是否有更深层次的技术原因?如果我mmap在这些前缀之外手动翻页会有问题吗?
我有一个要在 Oracle Linux OS 上运行的 C++ 应用程序。
考虑一下,我用new运算符创建了几个对象。虽然我已经使用 delete 操作符来解除分配它,但是 force kill 命令不会到达这个实现。
但是,如果我强制终止 ( kill -9) 进程,动态分配的内存(使用new运算符)是否会被操作系统取消分配?由于我无法找到直接的答案,因此我想了解一些信息。
提前致谢。
我正在尝试了解内存和页面错误,因此我编写了下面的代码来检查我的理解。我不明白为什么调用 malloc 会导致 MINFL 增加,因为 malloc() 不应该影响物理内存(据我所知)。
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
void main() {
printf("Before malloc\n");
getchar();
malloc(1 << 20);
printf("After malloc\n");
getchar();
}
Run Code Online (Sandbox Code Playgroud)
这些是 ps 命令的最终结果。
在进行 malloc 之前:

malloc 之后:

有两件事我不明白:
请帮忙并谢谢。