我对共享库有一个重大疑问.我研究的是,不同进程共享的库的虚拟地址对于所有这些进程都是相同的.但是我尝试通过以下命令集使用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) 我不是计算机专家,所以让我试着更具体地提出这个问题:
我做了一些科学计算,计算有时需要大量内存来存储结果.几天前,我的输出文件占用了4 GB的硬盘,但我有这么多的RAM.所以:
提前致谢!
大多数操作系统使用页面调度来存储虚拟内存。为什么是这样?为什么不使用细分?仅仅是因为硬件问题吗?在某些情况下,一个比另一个好吗?基本上,如果您必须选择一个,则要使用哪个?为什么?
出于参数考虑,我们假设它是x86。
我在一个资源非常有限的嵌入式环境中工作.我们正在尝试使用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进程使用的最大虚拟内存量?
我正在实现一个简单的VM,目前我正在使用运行时算术来计算单个程序对象地址作为基指针的偏移量.
我今天就这个问题提出了几个问题,但我似乎无处可去.
我从第一个问题中学到了一些东西 - 对象和结构成员访问和地址偏移计算 - 我了解到现代处理器具有虚拟寻址功能,允许计算内存偏移,而无需任何额外的周期用于算术.
问题二 - 在C/C++编译期间是否解决了地址偏移? - 我了解到手动进行偏移时无法保证这种情况发生.
到目前为止,我应该清楚的是,我想要实现的是利用硬件的虚拟内存寻址功能并从运行时卸载它们.
我正在使用GCC,就像平台一样 - 我在Windows上开发x86,但由于它是一个VM,我希望它能够在GCC支持的所有平台上高效运行.
因此欢迎任何有关该主题的信息,我们将非常感谢.
提前致谢!
编辑:关于我的程序代码生成的一些概述 - 在设计阶段,程序被构建为树层次结构,然后递归地序列化为一个连续的内存块,以及索引对象并计算它们从程序内存块的开头的偏移量.
编辑2:这是VM的一些伪代码:
switch *instruction
case 1: call_fn1(*(instruction+1)); instruction += (1+sizeof(parameter1)); break;
case 2: call_fn2(*(instruction+1), *(instruction+1+sizeof(parameter1));
instruction += (1+sizeof(parameter1)+sizeof(parameter2); break;
case 3: instruction += *(instruction+1); break;
Run Code Online (Sandbox Code Playgroud)
情况1是一个函数,它接受一个参数,该参数在指令之后立即找到,因此它作为指令的1个字节的偏移量传递.指令指针递增1 +第一个参数的大小以找到下一个指令.
情况2是一个函数,它接受两个参数,与之前相同,第一个参数作为1个字节的偏移量传递,第二个参数作为1个字节的偏移量加上第一个参数的大小.然后,指令指针增加指令的大小加上两个参数的大小.
情况3是goto语句,指令指针递增一个紧跟goto指令的偏移量.
编辑3:根据我的理解,操作系统将为每个进程提供自己专用的虚拟内存寻址空间.如果是这样,这是否意味着第一个地址总是......好零,所以从内存块的第一个字节开始的偏移实际上就是这个元素的地址?如果内存地址专用于每个进程,并且我知道程序存储器块的偏移量和每个程序对象与内存块的第一个字节的偏移量,那么在编译期间是否解析了对象地址?
问题是在编译C代码期间这些偏移是不可用的,它们在"编译"阶段和字节代码转换期间就已知.这是否意味着没有办法为"免费"进行对象内存地址计算?
例如,如何在Java中完成此操作,其中只将虚拟机编译为机器代码,这是否意味着由于运行时算术,对象地址的计算会降低性能?
有没有办法以编程方式检测?
另外,检测哪些进程正在颠簸的linux命令是什么?
我在我的应用程序中遇到了问题.我一直在测试,直到现在主要是在我的iPad 3上偶尔检查我的iPad 1,以确保一切顺利.
我正在我的应用程序中播放UIImageView动画,它在退出之前只保留"已接收内存警告"消息.
我一直在仪器中使用对象分配工具,但据此,我的内存使用率很低.所以在研究了一下之后,我发现了Larson先生的这篇文章:https://stackoverflow.com/a/5627221/329900
现在我正在使用Memory Monitor工具.但是,我不明白我为什么要放弃.第一代.iPad拥有256MB内存.现在我知道我不能全部使用...有人说你不应该使用超过100MB.
那是真正的记忆,还是虚拟记忆...或者可能是某种组合?我的实际内存一直在20到25MB之间,但崩溃时虚拟内存大约为190 - 205MB.
这是一个截图:
有人能够对此有所了解吗?
在课堂上的讲座中,提出了这些幻灯片并没有太多解释.

这些似乎都在解释同样的事情,但我不明白为什么有数据读取或写入的双向箭头.
第一张幻灯片对我没有意义,因为如何在不翻译的情况下读取或写入虚拟地址?
是第二张幻灯片说一旦CPU有物理地址就可以读写它吗?
"假设您的计算机具有16位虚拟地址和256字节的页面大小.系统使用从地址十六进制400开始的1级页表.也许您想要DMA ...谁知道?前几个页面保留用于硬件标志等.假设页表条目有8个状态位.8个状态位将是......"
http://www.youtube.com/watch?v=-3Rt2_9d7Jg
有人可以解释为什么答案是马克/杰西描述的吗?