i would like to know if it is possible to explicitly declare which memory type (physical or virtual memory) should be used by the C# application for performing different actions? Let me explain it by an example:
Lets say, i have a file of about 100 or 200 MB in size. I need to parse this file, access and analyze its contents and perform operations on the file contents. Would it be possible for me to specifically store the entire file and the contents of it on Virtual Memory instead of physical memory?
If it is possible, then are there any side-effects/precautions that one should keep in mind?
The reason behind my question is that I often have to deal with such huge files or datasets (retrieved from databases) and perform operations on them, part of which need not occur sequentially or be synchronized. I want to improve the execution time and performance of the application by parallelizing the non sequential parts, if possible.
Generally you don't (and shouldn't need to) have any insight into how physical memory is managed. In Windows and hence in the CLR everything is virtual memory.
Unless you have a specific problem you should just pretend everything is physical memory.
You can depend on the operating system to intelligently determine what should be kept in physical memory and what can be swapped out. Swapping only occurs if there's memory pressure anyway, i.e. if you allocate more memory than is physically available.
Also, 100-200 MB isn't all that much nowadays.
physical or virtual memory
You can't actually read from virtual memory. When you attempt to this causes a page fault and the OS will do a page swap and bring that virtual memory back into physical memory. So you are only ever reading from physical memory. While swapping a page in, it will swap out a page from RAM that has not been used recently.
From the app's perspective it appears everything is in physical memory. You do not need to concern yourself with what pages are in or out of physical memory, the OS will handle that.
Related
Performance wise, is it wrong to embed a file in a resource section of a dll?
This might seem silly, but aim trying to embed some info inside the dll which can later be fetched by some methods, in case the whole solution and documentation is lost and we have only the dll.
What are the downside of doing such a thing?
Is it suggested or prohibited ?
Embedded resources are done very efficiently. Under the hood, it uses the demand paged virtual memory capabilities of the operating system. The exact equivalent of a memory-mapped file. In other words, the resource is directly accessible in memory. And you don't pay for the resource until you start using it. The first access to the resource forces it to be read from the file and copied into RAM. And is very cheap to unmap again, the operating system can simply discard the page. There is no way to make it more efficient.
The other side of the medal is that it is permanently mapped into virtual memory. In other words, your process loses the memory space occupied by the resource. You'll run of out of available address space more quickly, an OutOfMemoryException is more likely.
This is not something you normally worry about until you gobble up, say, half a gigabyte in a 32-bit process. And don't fret about at all in a 64-bit process.
I have been reading about out of memory for some time now and I figured out that in most cases out of memory exception (at least in .NET) isn't really caused by system actually running out of memory but rather system could not allocate chunks of requested memory block due to fragmentation.
What I don't really understand is I've been in a situation where I still get out of memory exception even if I try to allocate a large chunk of contiguous memory on application startup (eg: loading 100 images). Since the application has just started up, it is assumed that not much allocations / de-allocations have been done prior to that, so there should be many free contiguous blocks available. In that case why would the application still get hit by memory fragmentation issue?
Note that I'm also fairly certain that the issue was not caused by the system actually running out of memory quota allocated for my application because loading 100 images in my specific case only takes ~200 mb or so.
In my experience, Out of Memory mostly means poor object management. It's symptomatic of creating too many objects too fast and GC is having a hard time keeping up. Setting aside the few projects that take and never give memory back (like a SQL Server) out of memory can be prevented with caching and a well defined object life cycle.
Is it better to pre-allocate (for example) 100KB of memory (in the heap) but then only go on to use 60KB, or is it better to allocate each byte as you need it?
My question arises from reading this blog:
http://deplinenoise.wordpress.com/2012/10/20/toollibrary-memory-management-youre-doing-it-wrong/
This really depends on intricate memory details of your application. However, the guy's fundamental point is absolutely accurate- pre-allocation and memory regions are obscenely efficient. new and delete are the most general tools possible, and if you have a more specific problem, you can find a much more efficient solution. Fixed-size object pools are another example.
It is. The operating system does not actually give you all that space anyway in some cases. Take Linux for example. Java tends to request large amounts of memory and never use it so what actually happens is that the OS keeps tracks of these ranges you requested but never maps them into the page tables (and therefore never allocates a frame for it) until you use it. So in terms of virtual memory it looks like you're using a lot but really you're only using the pages that you ever access (the 40kb in your example that you actually used). You can see this in the difference between virtual and physical usage of memory (assuming your processes aren't swapping out).
Im a little confused with regards to the memory limitations of an application. As far as i can see, if i write a c# application, targeting x64, my program will have access to 8TB of Virtual address space = space on the HD?
OS >= Windows 7 professional supports 192gigs of RAM. So if i had 192gig system (unfortunately i dont), i could load just over 8.1TB of data into memory (assuming no other processes were running)?
Is virtual memory only used when i have run out available ram? Im assuming there is a performance implication associated with virtual memory vs using RAM?
Apologies if these appear stupid questions, but when it comes to memory management, im rather green.
Your question is actually several related question, taking each individually:
OS >= Windows 7 professional supports 192gigs of RAM. So if i had 192gig system (unfortunately i dont), i could load just over 8.1TB of data into memory (assuming no other processes were running)?
No, it would still be 8 TB. That is the maximum amount of addressable space, whether it is in RAM or elsewhere.
However you could never have 8 TB in use, even if you some how unloaded Windows itself, as the OS needs to keep track of the space being used. In total, you could probably get to 7 TB approximately.
is virtual memory only used when i have run out available ram?
No, if you have virtual memory turned on the entirety of RAM is typically preloaded onto your HDD (give or take a few seconds). This allows the OS to unload something to make room if it feels the need, without having to persist the data. Note that the OS keep thorough track so will know if this is the case or not.
Im assuming there is a performance implication associated with virtual memory vs using RAM?
Depends on your context. Every seek on the hard drive takes a computational eternity, however it is still a fraction of a second. Assuming your process isn't thrashing and repeatedly accessing virtual memory, you should not notice a significant performance hit outside high performance computing.
Apologies if these appear stupid questions, but when it comes to memory management, im rather green.
Your main problem is you have some preconceived notions about how memory works that don't line up with reality. If you are really interested you should look into how memory is used in a modern system.
For instance, most people conceptualize that a pointer points to a location in memory, since it is the fundamental structure. This isn't quite true. In fact the pointer contains a piece of information that can be decoded into a location in the addressable space of the system, which isn't always in RAM. This decoding process uses quite a few tricks that are interesting, but beyond the scope of this question.
Normally, you should write applications targeting Any CPU. The .NET loader then decides (depending on the platform it is running on) which version of the run-time environment will execute the application and into what kind of native code it will be compiled. There is no need to specify the platform, unless you are using custom native components which will be loaded into the process created for your application. This process is then associated with some virtual address space - how that is mapped to physical memory is managed by the OS...
After reading a few enlightening articles about memory in the .NET technology, Out of Memory does not refer to physical memory, 597499.
I thought I understood why a C# app would throw an out of memory exception -- until I started experimenting with two servers-- both are having 2.5 gigs of ram, windows server 2003 and identical programs running.
The only significant difference between the two being one has 7% hard drive storage left and the other more than 50%.
The server with 7% storage space left is consistently throwing an out of memory while the other is performing consistently well.
My app is a C# web application that process' hundreds of MBs of String object.
Why would this difference happen seeing that the most likely reason for the out of memory issue is out of contiguous virtual address space.
All I can think of is that you're exhausting the virtual memory. Sounds like you need to run a memory profiler on the app.
I've used the Red Gate profiler in similar situations in the past. You may be surprised how much memory your strings are actually using.
Is the paging file fragmentation different on each machine? High fragmentation could slow down paging operations and thus exacerbate memory issues. If the paging file is massively fragmented, sort it out e.g. bring the server off-line, set the paging file size to zero, defrag the drive, re-create the paging file.
It's hard to give any specific advice on how to deal with perf problems with your string handling without more detail of what you are doing.
Why would this difference happen
seeing that the most likely reason for
the out of memory issue is out of
contiguous virtual address space?
With 7% free hard disk your server is probably running out of space to page out memory from either your process or other processes, hence it has to keep everything in RAM and therefore you are unable to allocate additional memory more often than on the server with 50% free space.
What solutions do you guys propose?
Since you've already run a profiler and seen at least 600MB+ of usage with all the string data you need to start tackling this problem.
The obvious answer would be to not hold all that data in memory. If you are processing a large data set then load a bit, process it and then throw that bit away and load the next bit instead of loading it all up front.
If it's data you need to serve, look at a caching strategy like LRU (least recently used) and keep only the hottest data in memory but leave the rest on disk.
You could even offload the strings into a database (in-memory or disk-based) and let that handle the cache management for you.
A slighty left-of-field solution I've had to use in the past was simply compressing the string data in memory as it arrived and decompressing it again when needed using the SharpZipLib. It wasn't that slow surprisingly.
I would agree that your best bet is to use a memory profiler. I've used .Net Memory Profiler 3.5 and was able to diagnose the issue, which in my case were undisposed Regex statements. They have demo tutorials which will walk you through the process if you're not familiar.
As you your question, any single reference to the strings, the jagged array for instance, would still prevent the string from disposing. Without knowing more about your architecture, it would be tough to make a specific recommendation. I would suggest trying to optimize your app before extending memory though. It will come back to bite you later.
An OutOfMemoryException is more likely to indicate fragmentation in your page file - not that you are out of RAM or disk space.
It is generally (wrongly) assumed that the page file is used as a swap disk - that RAM overflow is written to the page file. All allocated memory is stored in the page file and only data that is under heavy usage is copied to RAM.
There's no simple code fix to this problem other than trying to reduce the memory footprint of your application. But if you really get desperate you can always try PageDefrag, which is a free application originally developed by SysInternals.
There is a few tricks to increase memory (I dont know if it works with a web-app, but it looks like it does):
"Out of memory? Easy ways to increase the memory available to your program"
http://blogs.msdn.com/b/calvin_hsia/archive/2010/09/27/10068359.aspx