摘要我想各位读者应该对于 Linux 上的动态函式库的架构有了进一步的了解笔者根据自己电脑 Linux 的记忆体配置画了下面的架构图相信会让有心了解整个运作的人有了更清楚的一个印象
结束语
最后我想各位读者应该对于 Linux 上的动态函式库的架构有了进一步的了解笔者根据自己电脑 Linux 的记忆体配置画了下面的架构图相信会让有心了解整个运作的人有了更清楚的一个印象
在这张图中我们所执行的程序是由记忆体 x 开始载入的而所用到的动态函式库则是在记忆体位置 x 开始载入以笔者的电脑为例动态函式库载入的记忆体映射情况大略为
/usr/share/locale/en_US/LC_MESSAGES/SYS_LC_MESSAGES
/usr/share/locale/en_US/LC_MONETARY
/usr/share/locale/en_US/LC_TIME
b /lib/libnss_filesso
bc /lib/libnss_filesso
cf /lib/libcso
ffb /lib/libcso
fbff
ff /lib/ldso
/lib/ldso
b /lib/libnss_nisplusso ┅(more)
若我们程序透过 malloc 配置动态的记忆体则会配置在标示为 Free Space的记忆体空间中程序所用到的堆叠(Stack) 是由 xbfffffff 开始往下延伸
而在记忆体位置 xc 以上则是属于 Kernel Mode 的部分这部份包含了Linux Kernel 的 Image 以及我们之后所动态载入的模组
文章到此正式结束了读者若有任何的问题或是这篇文章有任何疏漏的部份欢迎各位可以来信指教谢谢各位^_^My EMail: tw
注一:(~mcculley/mapself/)笔者在写这篇文章时在一个网页上看到一个很有意思的记忆体区块拷贝效率比较我们知道在Linux下面如果要把记忆体区块由 A 拷贝到 B我们除了可以使用memcpy来完成以外还可以透过mmap来开启档案/proc/self/mem来完成拷贝记忆体区块的目的举个例子来说如果我们要把记忆体区块由A拷贝到B共 chunksize 个bytes可以透过如下的写法
memcpy(B A chunksize);
透过 mmap 来做的话可以藉由以下的写法
int self;
self = open(/proc/self/mem O_RDONLY);
B = mmap(B chunksize PROT_READ | PROT_WRITE
MAP_PRIVATE | MAP_FIXED self (off_t)A);
也就是透过 Linux 提供给每个 Process 的记忆体装置档案 mem来完成记忆体的拷贝动作
不过虽然我们可以有这两种方法可以选择可是遇到要拷贝记忆体时却不免会遇到要选择何种方式来实做的问题因此该网页的作者写了一个小程序来测试这两种方式的优缺点首先在 Linux 上每个记忆体的 Page 大小为 bytes因此测试时就是利用 bytes为单位来逐渐增加测试的记忆体区块大小每个阶段都有一个固定的记忆体区块大小与两个内容不同的记忆体区块作为拷贝时的来源端每一个循环都会先拷贝一个来源端到目的的记忆体区块中再比较内容若相同则拷贝另一个来源端的资料到目的的记忆体区块中再比较内容如此重复 次(表示共拷贝了 次到目的记忆体区块中)藉此来比较 memcpy 与 mmap 在执行记忆体区块拷贝时的效率
如下表(笔者电脑配备: PII MB RAM)
memcpy mmap
我们不难发现当记忆体区块为 时memcpy 都胜过mmap不过当拷贝的记忆体区块越来越大时mmap 明显表现的相当有效率像最后测试的记忆体区块大小为 bytesmmap 相较于 memcpy所花的时间少了约 秒钟
由此我们可以了解到如果在 Linux 上我们所撰写的系统需要使用较大的记忆体区块拷贝时透过 mmap 来作或许是一个不错的选择