When you write an application in C#, and then run it, will it not be compiled again next time it's run, or everything that's used is gonna be recompiled every time the application starts up?
How does JIT compiling works for caching?
For any DLL that is not in the ngen'd, every time you run the application, it will re-JIT the code that is used. There is no caching of the JIT code in between runs of the same non-ngen'd DLL.
EDIT Cleared up a mistake with GAC and NGEN
Related
I am trying to investigate a performance problem where an application runs slowly when run in 64bit on one of our servers, while it runs fast in 32 bit on that same machine or 64 bit anywhere else.
I have seen that this could be related to the JIT compiler being used. Is there a way I can tell which JIT compiler is being used to run my application? I'd like to see if it's different on the server than on the other computers where the 64 bit version works fine.
JIT Version
You can follow Hans' steps to verify that RyuJIT is loaded into your application. [2]
use the debugger to ensure you have the new version. First have a look-see at the runtime directory with Explorer, navigate to C:\Windows\Microsoft.NET\Framework64\v4.0.30319. You'll find the the two jitters there, clrjit.dll is new jitter based on the Ryujit project and compatjit.dll is the legacy x64 jitter.
Project > Properties > Debug > tick the "Enable native code debugging option". Use the Build tab and ensure you've removed the jitter forcing, the "Prefer 32-bit" option must be unticked, "Platform target" must be set to AnyCPU. And use the Application tab to pick the framework target.
Use Debug > Step Into to start debugging. Debug > Windows > Modules displays the list of loaded modules. Find the jitter DLLs back in that list, click the "Name" column header to sort by name. If you see compatjit.dll back then you are using the legacy jitter. Do note that you'll always see clrjit.dll, they both get loaded when the legacy jitter is used.
[2] https://stackoverflow.com/a/31534544/102351
JIT Architecture
You can determine the architecture of the JIT used by checking whether the running application is a 64-bit process or not.
Environment.Is64BitProcess
https://msdn.microsoft.com/en-us/library/system.environment.is64bitprocess.aspx
This property is implemented as a direct true/false return within the 64-bit and 32-bit versions of mscorlib, respectively. [1]
[1] https://stackoverflow.com/a/1913908
Use the JIT performance counters (https://msdn.microsoft.com/en-us/library/w8f5kw2e(v=vs.110).aspx#jit) to monitor when code is being jitted.
You can use ngen (https://msdn.microsoft.com/en-us/library/6t9t5wcf(v=vs.110).aspx) to improve application start-up time by removing the need to JIT code - ngen pre-compiles assemblies into native images.
Its very basic question.
JIT compilation is on demand as per MSDN MSIL To Native Code.
Every time when we run the assembly JIT compiler converts MSIL to Native language? Or When we run assembly first time, it converts and store the native language code to somewhere?
Thanks in advance!
The JIT compiler compiles your code when you start the application and stores it in memory.
This code can be cached by ngen.exe (Native Image Generator) and stored in the native image cache. This will be automatically loaded the next time you start the application, and you won't have to JIT the MSIL code a second time.
Ngen.exe creates native images, which are files containing compiled processor-specific machine code, and installs them into the native image cache on the local computer. The runtime can use native images from the cache instead of using the just-in-time (JIT) compiler to compile the original assembly.
The native image cache can be found on a path similar to C:\Windows\assembly\NativeImages_v4.0.30319_64. This path is not accessible through Windows Explorer, so use cmd or a powershell.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Disassembly view of C# 64-bit Release code is 75% longer than 32-bit Debug code?
I have an extremely simple C# Console Application, hat does some sorting on a big number of elements (only a few lines of code with array operations).
When I start the release code from Visual Studio IDE with F5 or Ctrl-F5 the program is about 3x slower than when started directly from Win-Explorer.
41.140 seconds when launched from VS 2010 IDE
13.950 seconds when launched by double-clicking myprogram.exe
Why???
First some details...
Be aware that there are 2 main "optimization" stages in .NET.
At the C# Compiler level...the production of different IL (Intermediate Language)...optimized or non-optimized....controlled by whether your project sets the DEBUG flag or not
At the JITer level...when the IL is translated into machine code (either through Just-in-Time compilation or via NGEN)....optimized machine code may or may not be producedNote: it is NOT the IL produced via the compiler in DEBUG or RELEASE mode that controls the JITter optimization setting...it's an independent setting.
The main optimization "wins" occur at the JIT level.
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/57db50f1-54c7-4730-a097-c4976bb3a30b/
When you are debugging a NET program through Visual Studio, normally you don't want the JITter to produce optimized machine code, because then your program source statements aren't closely in sync with the executing code when you step through it.
So that's why there is an option in Visual Studio to turn off JITter optimizations (this is comparable to turning off JITter optimizations with the AllowOptimize=0 flag)...and by default Visual Studio turns JITter optimizations off:
See this for an explanation of the Suppress option:
http://msdn.microsoft.com/en-us/library/ms241594(v=vs.85).aspx
When you run a NET application outside of Visual Studio it doesn't matter if that program was compiled as DEBUG (non-optimized IL) or RELEASE (optimized IL)....the JITter will produce optimized machine code by default.
So the behaviour to be noticed is that a NET program will run
substantially faster when started outside of Visual Studio than when
started from Visual Studio due to the different JITter optimization
setting...even when it's a RELEASE mode application....as #Knasterbax
observed. In addition, there's additional overhead to add when debugging (F5) and not just running (CTRL+F5) from Visual Studio.
If you run your application (whether RELEASE or DEBUG) from Explorer and then you "attach" to the process with Visual Studio, then your application will be using a JITter that is applying optimizations....your code will run faster...but any source code stepping will not be in sync.
If you untick the "Suppress JIT optimizations" then you can gain faster execution at the expense of a poorer debugging experience in Visual Studio.
To end, there is a way to turn off JITter Optimizations for your application code should you need/want to:
disable JITter for entire application by putting this into app.config
[.NET Framework Debugging Control] AllowOptimize=0
you can tell the JITter not to optimize specified methods by using this attribute
[MethodImpl(MethodImplOptions.NoOptimization)]
on method bodies.
F5 is start debugging, not "run", it will be doing a lot of things like loading symbols in the background, even if you're attempting to debug a release build.
Starting a program with the debugger attached will always be significantly slower than without it.
When you compile the code in debug mode, the compiler switches off some optimisations, and it adds some extra instructions, to make it possible to put breakpoints everywhere and to make it possible to single step through the code.
This will make code compiled in debug mode slower than code compiled in release mode.
I am using DllImport to access some functions in a C++ dll from my C# application.
This code works fine on my dev laptop, which is Windows 7 64bit, the dll itself is 32 bit, so I run the process hosting the dll in 32bit and it works well. However when I try to run the exact same process on my target machine, which is again, Windows 7 64bit Ultimate i get the error 'Invalid access to memory location.' from the process.
I'm not sure what the problem is, i've looked at loads of resources on the net and none of them have solved it for me. I dont understand why it works fine on my dev box, but not on the target?
The dll itself is fine, the examples that come with the dll all work fine on my target box (which are C# apps doing DllImport).
Has anyone else had this problem? Been fighting it for two days now!
Exception: {"Unable to load DLL 'CLEyeMulticam.dll': Invalid access to memory location. (Exception from HRESULT: 0x800703E6)"}
The DLL loading may crash because of unresolved dependencies, so open your DLL on target machine using Dependency Walker and see is there any problems.
I notice one big difference between your dev machine and your target machine, the dev environment. Make sure you have all the necessary redistributables on the target machine.
Edit: I have seen similar issues when some dlls were compiled to different versions of the .Net framework or if they were made with different versions of Visual Studio, as the redistributables for each version are different and the latest redistributables are not exactly backwards compatible.
I had the same problem here Native loading works good. Loading from .net gives error Unable to load DLL 'my.dll': Invalid access to memory location
The problem was in DEP feature. When I switched on DEP for essential programs only, it gave no effect. But when I completely switched off DEP, and rebooted my server, error has gone. The one more thing I've done - installed latest updates for .net 4.0
The one notable thing - i didn't see any errors about DEP, just closing with "memory" error.
I've had this issue before. I think your problem is with VS trying to open the file but not having permissions to read it. You need to make sure the account you're using has access to the DLL. Try disabling UAC to see if it works, or use an Administrator account. Or try giving Full Control on the DLL to Everyone.
EDIT: Could you run VS as administrator (right click -> Run As Administrator)? Could you put the DLL onto your desktop to try? Is there a folder structure difference between your working computer and the one that's failing? Also, can the DLL run fine if you execute it outside of VS (try running it as admin as well)?
HTH
I have had similar problems before, try the following.
Check the .NET CLR version. Are there any SPs/KBs present in your target that is not in your dev?
Try loading the debug version of the C++ DLL. Are you able to load it? If it fails, I'd suggest starting your app under WinDBG in your target. Once the exception is hit, a simply !analyze -v will give you lots of info.
As a next step, I'd try to reproduce this issue in a unit test environment. Are the C# samples you mentioned built for x64 VM? If not, try doing that and try running the resulting sample binary in your target. Is the issue reproducible?
I have encountered a problem with a 64bit .NET app ("Any CPU") trying to load a 32bit native DLL dependency. I don't have the error message in front of me, so I can't tell you if it is the same problem. The solution for my problem was to change my build to x86-only.
If the bit size of the DLL is changing on each box, maybe there are structure size differences, so your PInvoke signature becomes incorrect. This could easily cause a buffer overrun, and cause stack corruption in the native code.
If you're getting the error in your C# app, this message often indicates the native code did something nasty to memory that the ILM can see - check the code in/called by your DllMain routine - that is called before your call actually goes thru - if it's misbehaving, you'd see this result
#Merlyn Morgan-Graham We faced a similar problem. Where we built the .Net application with "Any CPU" build and tried using with 32 bit C++ Dll. When we run the .Net Application in 64 bit OS. It runs as 64 bit executable and hence and got similar issue. After buidling in X86 Loading, Calls to C++ Dlls worked absolutely fine. One more important thing is if you are using C++ DLL in your .Net code. There would be fair amount of marshalling, so it is important to stick to the build type (i.e. X86, any CPU or X64).
Please check the following link also:
Windows Vista: Unable to load DLL 'x.dll': Invalid access to memory location. (DllNotFoundException)
The obvious, but probably lame solution would be to build C# side explicitly for 32-bit. Check how do you create out of proc host - programatically or by populating registry keys or ... could be that on other box it gets set up to either make 64-bit hosting process or attempt in-proc invocation, which means loading ... It it's a registry setting don't forget that for mixed 23/64 bit cases there are two branches to dig into.
I ran into a similar issue when I moved to win7. You might need to set your (64 bit) machine to run as a 32bit one by-default, using the below command:
C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\Ldr64.exe setwow
Ref:
http://social.msdn.microsoft.com/Forums/en/phoenix/thread/9a43e9a1-a744-4a1a-bb34-3604254c126b
I am running performance profile for a C# application on a virtual machine.
The results shows a huge load of "JIT Compiler". When I dig further, it shows something called "Class Loader" as the only method getting called by JIT compiler.
What should I do to bring "JIT compiler" load down?
JIT is the 'Just In Time' compiler, this essentially compiles your C# into executable code that can work on the current processor.
.Net comes with a utility called NGEN, this creates a native image of your C# code, that doesn't need to be JIT'ted. There are downsides to this however, have a read of this:
http://codeidol.com/csharp/net-framework/Assemblies,-Loading,-and-Deployment/Native-Image-Generation-%28NGen%29/
And finally here's a link to the MS info about NGEN:
http://msdn.microsoft.com/en-us/library/6t9t5wcf%28VS.80%29.aspx
You could try using NGEN to pre-JIT your assemblies to native images. This will lessen Jitting overhead on application load:
http://msdn.microsoft.com/en-us/library/6t9t5wcf(VS.80).aspx
You should run this tool on the machine where your assemblies are i.e. your virtual machine.