Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the .NET framework lock dlls?

Tags:

c#

.net

Since DLLs get loaded in memory, is there any reason why reference dlls have to be locked by the running process? Is there any way around the locking other than copying the dlls to a temp folder and loading from there?

like image 948
edeboursetty Avatar asked May 07 '14 21:05

edeboursetty


People also ask

What is the purpose of .DLL file in C #?

In Windows, a dynamic-link library (DLL) is a kind of executable file that acts as a shared library of functions and resources. Dynamic linking is an operating system capability. It enables an executable to call functions or use resources stored in a separate file.

How do I lock a DLL file?

Basically, you can't. The problem is that in order to be at all useful, the DLL files has to be readable by the computer - which means it's readable by a user as well.


1 Answers

It is a side-effect of the CLR creating a memory-mapped view of an assembly to map it into memory. Memory mapped files are a low-level feature in Windows, also exposed in .NET 4.0 with the MemoryMappedFile class. Otherwise a common feature in a demand-paged virtual memory operating system like Windows.

MMFs have lots of desirable properties. The act of "loading" an assembly becomes very simple and very fast. Nothing is actually read from the file, it happens in a lazy fashion. Every byte in the file has a corresponding memory address. When the CLR tries to read a byte in the assembly metadata or IL for the first time, the processor trips a page fault since the page is not available in RAM. The operating system handles it by dynamically reading the file content from the disk. The CLR continues as though nothing happens, it is completely unaware of what happened.

This kind of lazy access is great, you don't pay for what you don't use. So if you need a single method from a single type in, say, a big assembly like Microsoft.VisualBasic.dll then you only pay for that method. Your program never actually reads the metadata of other types or the IL of other methods.

There's more. You don't pay for committing the memory either. If another process on the machine needs RAM then pages that contain assembly data can simply be discarded. Since they can just be reloaded from the file. They don't have to be backed by the paging file, cheapest virtual memory you can buy.

There's more. The fact that assembly data always needs to be reloadable from the file at any moment in time also means that it can never be correct to allow anybody to modify the file. Since that would cause the data in RAM to mismatch the data in the file. And for it to randomly change from the CLR's point of view since it cannot observe the page faults. So an MMF puts a hard lock on the file, nobody can mess with it. It is a free anti-malware feature.

There's more. The lock guarantee also means that the CLR never has to deal with jitted code no longer matching the IL in the assembly. Something that would be extraordinarily hard to implement since random changes in the assembly are next to impossible to synchronize properly with code execution. And it would be horribly expensive, method calls could not be simple CALL instructions anymore. And it isn't limited to code, a delegate object's target method would have to be dynamically resolved. Very major perf killers. Otherwise a solved problem, this is why the CLR supports the notion of an AppDomain. Unloading an appdomain destroys everything, code and data. The underlying technique behind shadow-copying assemblies, as used in high-availability applications like ASP.NET

like image 71
Hans Passant Avatar answered Nov 15 '22 19:11

Hans Passant