dll在物理内存里只有一份吗?

Icedmilk 2010-02-09 04:52:06
那些kernal32 user32 什么的,基本上是个程序就要加载这个些dll
在物理内存地址空间里他们只有一份吗?
...全文
435 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
hlq83 2010-02-10
  • 打赏
  • 举报
回复
看来我理解错了,以前认为只有数据段才是cpoy-on-write机制,刚试了下 代码段确实也是这样的,看来这样也是很有道理的,毕竟有些进程load dll时会指定base address。
donil 2010-02-10
  • 打赏
  • 举报
回复
loadlibrary时,不会创建dll副本,但如果是静态加载dll,会有多个副本。
Icedmilk 2010-02-09
  • 打赏
  • 举报
回复
引用 4 楼 wangk 的回复:
通常Dll页面是PAGE_EXECUTE_WRITECOPY属性。

参考MSDN对其说明:
Enables execute, read, and write access to the committed region of image file code pages. The pages are sharedread-on-write andcopy-on-write.

nb人说话总是一针见血,一句废话没有,可惜我对英文不敏感.
感谢20楼和22楼让我明白"写时复制"这个词.
6楼你再给点详细解释就更好了.

其实对于写操作来说,dll在内存中就是多份的,但是我以前不知道这个多份是什么时候产生的,
甚至以为就在loadlibrary时,就创建了dll的副本.
但现在明白了,只有在对dll进行写操作的时候才会创建副本.

好了,结贴给分.
hlq83 2010-02-09
  • 打赏
  • 举报
回复
引用 16 楼 icedmilk 的回复:
引用 15 楼 hlq83 的回复:应该只有一份,只是一些全局变量在每个进程中有副本。
有的代码改的不是变量

改的就是活生生的代码

如果我在一个进程里把kernal32.dll里的CreateProcess这个函数的代码给改了,
如果物理内存里只有一份kernal32.dll,那所有进程执行CreateProcess这个函数,执行的就是错的!

全局钩子本来就可能导致系统出错,所以安装钩子的server要保证勾住每一个调用CreateProcess的进程。
MoXiaoRab 2010-02-09
  • 打赏
  • 举报
回复
引用 18 楼 vincent_1011 的回复:
兔子也不是这样说吧

楼主想问的应该是当前内存。你说的那样改的话,要重启才行了。

还有进程刚加载的时候,代码段也就只有一份在物理内存中,就算是每个进程都要加载这个dll

那像15楼说的改入口点。这里有一个机制,写时复制,copy-on-write,你一改的话,这时候系统就单独给你copy一块出来了。这样你的修改影响不了别人。

这是我的理解。。。。希望没误导别人或者兔子再补充,我知道兔子对底层功力很深厚的,哈

你说得很正确,我没有要补充的。

就是Copy-on-Write,物理内存中有单个内存的拷贝页。互相之间不影响

修改过之后,系统为你维护一个新的修改的拷贝
lmxmx 2010-02-09
  • 打赏
  • 举报
回复
“写时复制”4个字,就是LZ解决此疑问的关键^^
lmxmx 2010-02-09
  • 打赏
  • 举报
回复

可以参照此帖:
http://topic.csdn.net/u/20070829/11/902d909d-339c-4ece-ba13-2c5d826d85a1.html
magic7004 2010-02-09
  • 打赏
  • 举报
回复
只有一份,但如果修改的话,修改的页会被copy
lmxmx 2010-02-09
  • 打赏
  • 举报
回复
路过,顺便学习一下^^
vincent_1011 2010-02-09
  • 打赏
  • 举报
回复
兔子也不是这样说吧

楼主想问的应该是当前内存。你说的那样改的话,要重启才行了。

还有进程刚加载的时候,代码段也就只有一份在物理内存中,就算是每个进程都要加载这个dll

那像15楼说的改入口点。这里有一个机制,写时复制,copy-on-write,你一改的话,这时候系统就单独给你copy一块出来了。这样你的修改影响不了别人。

这是我的理解。。。。希望没误导别人或者兔子再补充,我知道兔子对底层功力很深厚的,哈
MoXiaoRab 2010-02-09
  • 打赏
  • 举报
回复
你加载的时候,自己的进程里面只是一个拷贝,随你怎么玩野影响不了别人。

如果你去KnownDlls那个Section里面搞的话,就影响所有人了。

明白?
Icedmilk 2010-02-09
  • 打赏
  • 举报
回复
引用 15 楼 hlq83 的回复:
应该只有一份,只是一些全局变量在每个进程中有副本。

有的代码改的不是变量

改的就是活生生的代码

如果我在一个进程里把kernal32.dll里的CreateProcess这个函数的代码给改了,
如果物理内存里只有一份kernal32.dll,那所有进程执行CreateProcess这个函数,执行的就是错的!
hlq83 2010-02-09
  • 打赏
  • 举报
回复
应该只有一份,只是一些全局变量在每个进程中有副本。
Icedmilk 2010-02-09
  • 打赏
  • 举报
回复
上面打错字了

您再说到文件 那更就只有一份了

我就问,当一个程序加载dll的时候
如果dll内存里根本没有,肯定要去硬盘里装载, 装载之后如果再有进程要加载这个dll的时候,
是将内存里的dll再复制一份之后进行地址映射?
还是不复制,所有的进程里的这个dll都映射到同一个物理地址空间?
Icedmilk 2010-02-09
  • 打赏
  • 举报
回复
您在说到文件 那更就只有一份了

我就问,当一个程序加载dll的时候
如果dll内存里根本没有,肯定要去内存里装载, 装载之后如果再有进程要加载这个dll的时候,
是将内存里的dll再复制一份之后进行地址映射?
还是不复制,所有的进程里的这个dll都映射到同一个物理地址空间?
MoXiaoRab 2010-02-09
  • 打赏
  • 举报
回复
引用 10 楼 icedmilk 的回复:
既然是拷贝过来了,还可以说物理内存里只有一份吗?

Object本体只有一份。
chenyu2202863 2010-02-09
  • 打赏
  • 举报
回复
物理内存内只有一份!
Icedmilk 2010-02-09
  • 打赏
  • 举报
回复
既然是拷贝过来了,还可以说物理内存里只有一份吗?
MoXiaoRab 2010-02-09
  • 打赏
  • 举报
回复
自己用的时候只是拿了一个拷贝过来。自己改了不影响别人的。

如果你去KnownDlls里面改了,那么就会影响到所有进程
MoXiaoRab 2010-02-09
  • 打赏
  • 举报
回复
LZ 概念不清。。。。
那几个DLL和其他的DLL不同,系统里面有专门的映射区KnownDlls。
加载更多回复(7)

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧