I'm having a REALLY tough time with something. I'm using C#, and I want to be able to check whether the virtual memory paging file is currently enabled (or has a maximum size greater than 0, whichever is easier to test).
I haven't found any way to do it (if there is one, please tell me!), but I thought I might be able to indirectly accomplish my goal by just checking either how much memory in the paging file my program/process is using or even how much it's allowed to use.
So I was using the Process.PagedMemorySize64 and Process.PagedSystemMemorySize64 functions, but they return a positive number even when I have the paging file disabled! I was told elsewhere that those functions will tell me information about physical memory if a paging file is unavailable. Well great, because that doesn't help me.
So if anyone knows how to actually get any information about how much memory the current process or whole computer is either using or allowed to use within a paging file, I'd appreciate it!
P.S.: As a related question, does anyone ever get an OutOfMemoryException while trying to write an array into a FileStream in a loop? I mean I'm not actually allocating any memory at that time, and it only happens when I try to write huge files - the small ones write just fine.
Related
We’ve got a process that obtains a list of files from a remote transatlantic Samba share. This is naturally on the slow side, however it’s made worse by the fact that we don’t just need the names of the files, we need the last write times to spot updates. There’s quite a lot of files in the directory, and as far as I can tell, the .NET file API insists on me asking for each one individually. Is there a faster way of obtaining the information we need?
I would love to find a way myself. I have exactly the same problem - huge number of files on a slow network location, and I need to scan for changes.
As far as I know, you do need to ask for file properties one by one.
The amount of information transferred per file should not be high though; the roundabout request-response time is probably the main problem. You can help the situation by running multiple requests in parallel (e.g. using Parallel.ForEach)
The answer to your question is most likely no, at least not in a meaningful way.
Exactly how you enumerate the files in your code is almost irrelevant since they all boil down to the same file system API in Windows. Unfortunately, there is no function that returns a list of file details in one call*.
So, no matter what your code looks like, somewhere below, it's still enumerating the directory contents and calling a particular file function individually for each file.
If this is really a problem, I would look into moving the detection logic closer to the files and send your app the results periodically.
*Disclaimer: It's been a long time since I've been down this far in the stack and I'm just browsing the API docs now, there may be a new function somewhere that does exactly this.
Let's say I received a .csv-File over network,
so I have a byte[].
I also have a parser that reads .csv-files and does business things with it,
using File.ReadAllLines().
So far I did:
File.WriteAllBytes(tempPath, incomingBuffer);
parser.Open(tempPath);
I won't ever need the actual file on this device, though.
Is there a way to "store" this file in some virtual place and "open" it again from there, but all in memory?
That would save me ages of waiting on the IO operations to complete (good article on that on coding horror),
plus reducing wear on the drive (relevant if this occured a few dozen times a minute 24/7)
and in general eliminating a point of failure.
This is a bit in the UNIX-direction, where everything is a file-stream, but we're talking windows here.
I won't ever need the actual file on this device, though. - Well, you kind of do if all your API's expect file on the disk.
You can:
1) Get decent API's(I am sure there are CSV parsers that take Stream as construtor parameter - you then can possibly use MemoryStream, for example.)
2) If performance is serious issue, and there is no way you can handle the API's, there's one simple solution: write your own implementation of ramdisk, which will cache everything that is needed, and page stuff to hdd if necessary.
http://code.msdn.microsoft.com/windowshardware/RAMDisk-Storage-Driver-9ce5f699 (Oh did I mention that you absolutely need to have mad experience with drivers :p?)
There's also "ready" solutions for ramdisk(Google!), which means you can just run(in your application initializer) 'CreateRamDisk.exe -Hdd "__MEMDISK__"'(for example), and use File.WriteAllBytes("__MEMDISK__:\yourFile.csv");
Alternatively you can read about memory-mapped files(>= C# 4.0 has nice support). However, by the sounds of it, that probably does not help you too much.
I have a program that is pretty much modeled after the Answer by Alexander here:
Working example of CreateJobObject/SetInformationJobObject pinvoke in .net?
However, I want to also limit the amount of memory each child process can use, and I have absolutely no idea how to do it. I see the ProcessMemoryLimit in JOBOBJECT_EXTENDED_LIMIT_INFORMATION, but really haven't the slightest idea what data I need to put there. is it just a number in KB? Is there an object I need to build? And I can't seem to find any documentation on the matter.
Anyone have experience here?
I'm writing a c# application that takes a string to any friendly process name(say 'notepad') and reads the process memory. It is fine for reading bytes but I have no idea if those are int32s, chars, bools or other types of data. One of the first steps to solving that is knowing how the data is padded. how can I determine the data alignment of the memory?
I've learned it isn't as simple as knowing the OS or processor. Different packings are supposedly possible even then: http://www.developerfusion.com/article/84519/mastering-structs-in-c/
So, is there some pinvoke I could use on the process handle to read some value or maybe an algorithm that reads some bytes and tests what it finds?
Motivation(in case someone has a better solution for my end goal): I don't want to look for potential int32 values(or any other type) by looking at relative address 0,1,2,3 and then looking at 1,2,3,4 and so on if I can help it. If memory is say 4-byte aligned, I'd be wasting a lot of effort for nothing when I could just check 0,1,2,3 and skip to 4,5,6,7.
I'm not quite sure what you're trying to do - but my best bet is that you're hoping to dig around the process to find a bug or get an idea what they're up to?
the best way to figure out the memory layout will be from the symbols (.pdb). Is this an app that you've written?
Assuming not, you might consider injecting a thread and then calling MiniDumpWriteDump(). This API can dump the memory to disk where you can browse it with windbg.
The idea here will to use the Microsoft public symbols (!symfix) and then to go routing around the memory looking for whaterver you're needing. having the symbols for the Microsoft bits will help you - with those you'll be able to figure out where threads/heaps/handles/etc are located
I have to create a C# program that deals well with reading in huge files.
For example, I have a 60+ mB file. I read all of it into a scintilla box, let's call it sci_log. The program is using roughly 200mB of memory with this and other features. This is still acceptable (and less than the amount of memory used by Notepad++ to open this file).
I have another scintilla box, sci_splice. The user inputs a search term and the program searches through the file (or sci_log if the file length is small enough--it doesn't matter because it happens both ways) to find a regexp.match. When it finds a match, it concatenates that line with a string that has previous matches and increases a temporary count variable. When count is 100 (or 150, or 200, any number really), then I put the output in sci_splice, call GC.Collect(), and repeat for the next 100 lines (setting count = 0, nulling the string).
I don't have the code on me right now as I'm writing this from my home laptop, but the issue with this is it's using a LOT of memory. The 200mB mem usage jumps up to well over 1gB with no end in sight. This only happens on a search with a lot of regexp matches, so it's something with the string. But the issue is, wouldn't the GC free up that memory? Also, why does it go up so high? It doesn't make sense for why it would more than triple (worst possible case). Even if all of that 200mB was just the log in memory, all it's doing is reading each line and storing it (at worst).
After some more testing, it looks like there's something wrong with Scintilla using a lot of memory when adding lines. The initial read of the lines has a memory spike up to 850mB for a fraction of a second. Guess I need to just page the output.
Don't call GC.Collect. In this case I don't think it matters because I think this memory is going to end up on the Large Object Heap (LOH). But the point is .Net knows a lot more about memory management than you do; leave it alone.
I suspect you are looking at this using Task Manager just by the way you are describing it. You need to instead use at least Perfmon. Anticipating you have not used it before go here and do pretty much what Tess does to where it says Get a Memory Dump. Not sure you are ready for WinDbg but that maybe your next step.
Without seeing code there is almost no way to know what it is going on. The problem could be inside of Scintilla too, but I would check through what you are doing first. By running perfmon you may at least get more information to figure out what to do next.
If you are using System.String to store your matching lines, I suggest you try replacing it with System.Text.StringBuilder and see if this makes any difference.
Try http://msdn.microsoft.com/en-us/library/system.io.memorymappedfiles.memorymappedfile(VS.100).aspx