我对共享库有一个重大疑问.我研究的是,不同进程共享的库的虚拟地址对于所有这些进程都是相同的.但是我尝试通过以下命令集使用proc文件系统来查看相同的内容:
$ cat /proc/*/maps | grep /lib/libc-2.12.1.so
Run Code Online (Sandbox Code Playgroud)
输出是:
0025a000-003b1000 r-xp 00000000 08:07 1046574 /lib/libc-2.12.1.so
003b1000-003b2000 ---p 00157000 08:07 1046574 /lib/libc-2.12.1.so
003b2000-003b4000 r--p 00157000 08:07 1046574 /lib/libc-2.12.1.so
003b4000-003b5000 rw-p 00159000 08:07 1046574 /lib/libc-2.12.1.so
0086d000-009c4000 r-xp 00000000 08:07 1046574 /lib/libc-2.12.1.so
009c4000-009c5000 ---p 00157000 08:07 1046574 /lib/libc-2.12.1.so
009c5000-009c7000 r--p 00157000 08:07 1046574 /lib/libc-2.12.1.so
009c7000-009c8000 rw-p 00159000 08:07 1046574 /lib/libc-2.12.1.so
00110000-00267000 r-xp 00000000 08:07 1046574 /lib/libc-2.12.1.so
00267000-00268000 ---p 00157000 08:07 1046574 /lib/libc-2.12.1.so
00268000-0026a000 r--p 00157000 08:07 1046574 /lib/libc-2.12.1.so
0026a000-0026b000 rw-p 00159000 08:07 1046574 /lib/libc-2.12.1.so …Run Code Online (Sandbox Code Playgroud) 我在一个资源非常有限的嵌入式环境中工作.我们正在尝试使用node.js,它运行良好,但通常消耗大约60兆字节的虚拟内存(实际使用的内存大约为5兆字节.)鉴于我们的限制,这是太多的虚拟内存; 我们只能允许node.js最多使用大约30兆字节的VM.
node.js有几个命令行选项,例如"--max_old_space_size"," - max_executable_size"和"--max_new_space_size",但经过实验,我发现这些都控制了实际的内存使用,而不是最大虚拟内存大小.
如果重要,我正在使用ARM体系结构的ubuntu linux变体.
是否有任何选项或设置允许设置允许node.js进程使用的最大虚拟内存量?
有没有办法以编程方式检测?
另外,检测哪些进程正在颠簸的linux命令是什么?
在链接时重定位期间,链接器将运行时地址分配给生成的可执行文件中的每个节和每个符号
这些运行时地址是否对应于虚拟地址?
如果生成可执行文件的系统不使用虚拟内存怎么办?
接下来,如果不使用虚拟内存,则应用程序的地址空间将限制为加载时重定位后操作系统为其分配的物理地址空间
我认为,确实如此:如果包含所请求的物理地址的物理页尚未存储在 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 )中找不到这些常量。
假设一个简单的 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 可以根据该值分配内存区域吗?
通过运行一个简单的程序,less /proc/self/maps我发现大多数映射都以55and开头7F。我还注意到每当我调试任何二进制文件时都会使用这些范围。
此外,该评论在这里表明,内核的确有些范围的偏好。
这是为什么?上述范围是否有更深层次的技术原因?如果我mmap在这些前缀之外手动翻页会有问题吗?
我有一个要在 Oracle Linux OS 上运行的 C++ 应用程序。
考虑一下,我用new运算符创建了几个对象。虽然我已经使用 delete 操作符来解除分配它,但是 force kill 命令不会到达这个实现。
但是,如果我强制终止 ( kill -9) 进程,动态分配的内存(使用new运算符)是否会被操作系统取消分配?由于我无法找到直接的答案,因此我想了解一些信息。
提前致谢。