请问:如何查看DLL动态链接库的引用数

时间:2022-05-01 15:51:57
我有个问题:据说DLL动态链接库可以被多个程序引用,
比如dll.dll分别被程序A、B引用,也就是A和B程序都
可以使用动态库dll.dll中的函数,如果这样的话,那么
是放在公共的内存部分吗?进程A在调用动态库dll.dll时,
不是应该在同一个进程空间吗?如果这样,程序B怎么能
引用另一个进程空间中的动态库呢?
如果可以引用的话,如何查看动态链接库的引用数呢?

13 个解决方案

#1


A,B运行的时候系统都会给他们分配一块内存空间。
DLL是分页加载到A,B各自的进程空间里。
互不相干扰。

#2


dll加载对各个进程来说都有一份copy,但是对系统物理内存来说只有一份copy (除了可写数据段),调用计数归零则物理内存中的copy也被移除,同时关闭相应的文件句柄。

#3


引用 1 楼 m617105 的回复:
A,B运行的时候系统都会给他们分配一块内存空间。
DLL是分页加载到A,B各自的进程空间里。
互不相干扰。

也就是说A、B进程的内存空间都有DLL的副本,那不是就有3份了吗:A、B进程各一份,再加上原来的1份?
那如果很多进程都用到该DLL,那不是要占很大的内存空间吗?

 

#4


引用 2 楼 Idle_ 的回复:
dll加载对各个进程来说都有一份copy,但是对系统物理内存来说只有一份copy (除了可写数据段),调用计数归零则物理内存中的copy也被移除,同时关闭相应的文件句柄。

不是说DLL可以被多个进程共享的吗?怎么会被复制到各个进程呢?
那系统物理内存的那份能否读到它的计数?

#5


引用 3 楼 leetow2006 的回复:
Quote: 引用 1 楼 m617105 的回复:

A,B运行的时候系统都会给他们分配一块内存空间。
DLL是分页加载到A,B各自的进程空间里。
互不相干扰。

也就是说A、B进程的内存空间都有DLL的副本,那不是就有3份了吗:A、B进程各一份,再加上原来的1份?
那如果很多进程都用到该DLL,那不是要占很大的内存空间吗?

 

程序加载DLL的时候
系统并不是将DLL的所有代码都加载到内存里,而是分页加载的。
所以实际情况是程序加载DLL的时候,程序本身在任务管理器中显示的占用的内存空间不怎么增加,只是页面文件有明显变化。

#6


请问:如何查看DLL动态链接库的引用数理解讨论之前请先学会如何 观察

VMMap 是进程虚拟和物理内存分析实用工具。 http://technet.microsoft.com/zh-cn/sysinternals/dd535533

#7


引用 5 楼 m617105 的回复:
程序加载DLL的时候
系统并不是将DLL的所有代码都加载到内存里,而是分页加载的。
所以实际情况是程序加载DLL的时候,程序本身在任务管理器中显示的占用的内存空间不怎么增加,只是页面文件有明显变化。

不管是不是分页加载,总之是,A进程与DLL是在同一个A进程空间,同时B进程也是和DLL
在同一个B进程空间,是不是可以这样理解呢?

#8


去看看 Copy-On-Write 机制,你就明白了。
为什么系统的高内存被保留系统自己了。

#9


应用程序启动多个实例,这多个进程的地址空间中,应用程序部分地址空间对应到physical storage上,都是一份(memory map的)。所以,如果一个实例尝试修改一个全局或静态变量时,如果没有copy-on-write,这个变量就会被污染。所以windows在使用 memory map装载应用程序时,对全局和静态变量识别,然后给存放这些变量的page设上copy-on-write属性,这样当一个实例尝试修改一个全局或静态 变量时,一个exceptin产生,windows捕获然后重新分配page出来给该实例使用,从而避免了污染。
DLL的处理方式和这个是一模一样的。

#10


引用 9 楼 Saleayas 的回复:
应用程序启动多个实例,这多个进程的地址空间中,应用程序部分地址空间对应到physical storage上,都是一份(memory map的)。所以,如果一个实例尝试修改一个全局或静态变量时,如果没有copy-on-write,这个变量就会被污染。所以windows在使用 memory map装载应用程序时,对全局和静态变量识别,然后给存放这些变量的page设上copy-on-write属性,这样当一个实例尝试修改一个全局或静态 变量时,一个exceptin产生,windows捕获然后重新分配page出来给该实例使用,从而避免了污染。
DLL的处理方式和这个是一模一样的。

看了不是很明白,是不是说进程A需要动态库DLL时,才拷贝到进程A自己的进程空间,同样,进程B也是如此?
还有就是是否能获取动态库的引用数?

#11


DLL 在加载不是想一块饼一样整体赋值内内存空间。
而是被映射到内存空间。
简单的说,操作系统,认为如果一个块所有人都一样的,那么内存就只要一个副本。
如果,当 DLL 里面的一个部分被修改,甚至是代码段,那么操作系统就把这个块复制一个私有的副本到这个进程。
然后你就可以修改。
这样,就可以防止被污染了。

#12


如果 DLL 某一个段被设置共享的。那么所有的应用程序就共享这个数据块了。此时修改就不会 CopyOnWrite 了。

#13


我现在也遇到了相同的疑问:
假设现有进程A和进程B,dll1和dll2和dl3,在dll1和dll2中调用了dll3并会将一定量的数据存入dll3.(不是共享数据)
然后进程A和进程B都调用了dll1和dll2中会把数据存入dll3的函数,那么现在一共有多少分dll3的copy?
是两份还是四份?

#1


A,B运行的时候系统都会给他们分配一块内存空间。
DLL是分页加载到A,B各自的进程空间里。
互不相干扰。

#2


dll加载对各个进程来说都有一份copy,但是对系统物理内存来说只有一份copy (除了可写数据段),调用计数归零则物理内存中的copy也被移除,同时关闭相应的文件句柄。

#3


引用 1 楼 m617105 的回复:
A,B运行的时候系统都会给他们分配一块内存空间。
DLL是分页加载到A,B各自的进程空间里。
互不相干扰。

也就是说A、B进程的内存空间都有DLL的副本,那不是就有3份了吗:A、B进程各一份,再加上原来的1份?
那如果很多进程都用到该DLL,那不是要占很大的内存空间吗?

 

#4


引用 2 楼 Idle_ 的回复:
dll加载对各个进程来说都有一份copy,但是对系统物理内存来说只有一份copy (除了可写数据段),调用计数归零则物理内存中的copy也被移除,同时关闭相应的文件句柄。

不是说DLL可以被多个进程共享的吗?怎么会被复制到各个进程呢?
那系统物理内存的那份能否读到它的计数?

#5


引用 3 楼 leetow2006 的回复:
Quote: 引用 1 楼 m617105 的回复:

A,B运行的时候系统都会给他们分配一块内存空间。
DLL是分页加载到A,B各自的进程空间里。
互不相干扰。

也就是说A、B进程的内存空间都有DLL的副本,那不是就有3份了吗:A、B进程各一份,再加上原来的1份?
那如果很多进程都用到该DLL,那不是要占很大的内存空间吗?

 

程序加载DLL的时候
系统并不是将DLL的所有代码都加载到内存里,而是分页加载的。
所以实际情况是程序加载DLL的时候,程序本身在任务管理器中显示的占用的内存空间不怎么增加,只是页面文件有明显变化。

#6


请问:如何查看DLL动态链接库的引用数理解讨论之前请先学会如何 观察

VMMap 是进程虚拟和物理内存分析实用工具。 http://technet.microsoft.com/zh-cn/sysinternals/dd535533

#7


引用 5 楼 m617105 的回复:
程序加载DLL的时候
系统并不是将DLL的所有代码都加载到内存里,而是分页加载的。
所以实际情况是程序加载DLL的时候,程序本身在任务管理器中显示的占用的内存空间不怎么增加,只是页面文件有明显变化。

不管是不是分页加载,总之是,A进程与DLL是在同一个A进程空间,同时B进程也是和DLL
在同一个B进程空间,是不是可以这样理解呢?

#8


去看看 Copy-On-Write 机制,你就明白了。
为什么系统的高内存被保留系统自己了。

#9


应用程序启动多个实例,这多个进程的地址空间中,应用程序部分地址空间对应到physical storage上,都是一份(memory map的)。所以,如果一个实例尝试修改一个全局或静态变量时,如果没有copy-on-write,这个变量就会被污染。所以windows在使用 memory map装载应用程序时,对全局和静态变量识别,然后给存放这些变量的page设上copy-on-write属性,这样当一个实例尝试修改一个全局或静态 变量时,一个exceptin产生,windows捕获然后重新分配page出来给该实例使用,从而避免了污染。
DLL的处理方式和这个是一模一样的。

#10


引用 9 楼 Saleayas 的回复:
应用程序启动多个实例,这多个进程的地址空间中,应用程序部分地址空间对应到physical storage上,都是一份(memory map的)。所以,如果一个实例尝试修改一个全局或静态变量时,如果没有copy-on-write,这个变量就会被污染。所以windows在使用 memory map装载应用程序时,对全局和静态变量识别,然后给存放这些变量的page设上copy-on-write属性,这样当一个实例尝试修改一个全局或静态 变量时,一个exceptin产生,windows捕获然后重新分配page出来给该实例使用,从而避免了污染。
DLL的处理方式和这个是一模一样的。

看了不是很明白,是不是说进程A需要动态库DLL时,才拷贝到进程A自己的进程空间,同样,进程B也是如此?
还有就是是否能获取动态库的引用数?

#11


DLL 在加载不是想一块饼一样整体赋值内内存空间。
而是被映射到内存空间。
简单的说,操作系统,认为如果一个块所有人都一样的,那么内存就只要一个副本。
如果,当 DLL 里面的一个部分被修改,甚至是代码段,那么操作系统就把这个块复制一个私有的副本到这个进程。
然后你就可以修改。
这样,就可以防止被污染了。

#12


如果 DLL 某一个段被设置共享的。那么所有的应用程序就共享这个数据块了。此时修改就不会 CopyOnWrite 了。

#13


我现在也遇到了相同的疑问:
假设现有进程A和进程B,dll1和dll2和dl3,在dll1和dll2中调用了dll3并会将一定量的数据存入dll3.(不是共享数据)
然后进程A和进程B都调用了dll1和dll2中会把数据存入dll3的函数,那么现在一共有多少分dll3的copy?
是两份还是四份?