|
Hi All,
I'm just working on a WPF desktop database app and I may have a scenario that I think could benefit from the occasional forced garbage collection. The only reason I'm really venturing down this path is that my user base are pretty savvy types and memory is *always* at a premium.
When the app starts up it's consuming around 50Mb of RAM nothing to complain about. However, during certain searches on the database this memory usage can escalate to 150Mb+. Say search 1 returns 60,000 records from the Db and in this scenario the memory jumps to 150Mb and a short time later another seach might only return a few hundred samples. I'm seeing the memory still at around the 150Mb mark whereas I want this to be immediately reduced to reflect the required RAM needed to represent that smaller search result set.
Is it worth exploring a forced GC.Collect() . I've been doing plenty of reading and it seems like the message is a little mixed on this. Some people seem to use it regularly, some say never use it. Microsoft seem to say leave it up to the CG to decide, but as I illustrated above I want to free that RAM as quickly as possible.
Thanks,
|
|
|
|
|
Jammer wrote: Is it worth exploring a forced GC.Collect().
Unless you really know what you're doing and why, no, it's not.
Jammer wrote: memory jumps to 150Mb and a short time later another seach might only return a few hundred samples. I'm seeing the memory still at around the 150Mb mark
Don't tell me you used TaskManager to determine this! It's lying to you. TM doesn't show you how much memory your app is actually using - it's showing you how much the .NET CLR has allocated to your app - including the rest of the managed heap that your app isn't using. Use PerformanceMonitor and the .NET Memory counters to see your apps actual usage.
You really don't have to worry about memory unless your app is really hanging onto it and not releasing it back to the managed pool. The .nET CLR does a very good job of managing the memory and returning whatever it can back to Windows, whenver Windows needs it.
Allocating object out of the managed pool is always faster than waiting for the CLR to get another block of memory from Windows, adding it to the Managed Heap, then allocating your object. That's why the CLR maintains a pool of memory that your app hasn't used yet.
Jammer wrote: but as I illustrated above I want to free that RAM as quickly as possible.
You don't have to. It's handled automatically whenever the CLR determines that is has an excessive amount of unused memory in the managed pool or Windows needs it back.
|
|
|
|
|
Dave Kreskowiak wrote: Unless you really know what you're doing and why, no, it's not.
Well, I obviously don't!
Dave Kreskowiak wrote: Don't tell me you used TaskManager to determine this! It's lying to you.
I did ... my bad!
Dave Kreskowiak wrote: Use PerformanceMonitor and the .NET Memory counters to see your apps actual usage.
Ok, will look into this now. I blatantly didn't do enough reading on this. Thanks for this input Dave, much appreciated.
Cheers,
|
|
|
|
|
I didn't mean to be nasty to you.
It's the third time this week I've had to describe how the .NET memory manager works. Everyone thinks that TaskManager is the "end all be all" of memory statistics, when it's not. Noone ever remembers that PerfMon even exists let alone that it can tell you FAR more about what's going on, and more accurately.
The last time I described this, the person didn't believe that TM could lie so badly. "yeah, TM is telling you that the app is using 100MB+ of RAM, but PerfMon says it's really using 18MB." Which one are you going to believe?
|
|
|
|
|
Dave Kreskowiak wrote: Big Grin I didn't mean to be nasty to you.
Hey Chap,
I didn't think you were. I've only been a .NETter for a little over a year and have a STACK ('scus the pun!) to learn yet.
I totally appreciate your input.
Cheers,
|
|
|
|
|
Dave Kreskowiak wrote: The .nET CLR does a very good job of managing the memory and returning whatever it can back to Windows, whenver Windows needs it.
I'm afraid this is not true in WPF. It SHOULD be, but it's not.
Christian Graus
Driven to the arms of OSX by Vista.
"I am new to programming world. I have been learning c# for about past four weeks. I am quite acquainted with the fundamentals of c#. Now I have to work on a project which converts given flat files to XML using the XML serialization method" - SK64 ( but the forums have stuff like this posted every day )
|
|
|
|
|
Hardly the CLR's fault though. I think it's more WPF being sloppy under the hood. I've only touched on WPF here and there. Simple forms and controls really. I haven't had the time with a 1 year old running around the house to do much of anything new. But, teaching him stuff has turned out to be alot more fun than WPF teaching me how to pull my hair out!
|
|
|
|
|
I am CG. I think you want to force GC. Doing so, can make the number in the task manager lower, and while it's not accurate, WPF is also crap at this, you get no dispose methods and if you swap a lot of images, memory will leak and your app will crash.
Jammer wrote: Microsoft seem to say leave it up to the CG to decide,
OK, well, no-one ever calls me, so I really don't get to decide at all.....
They say that, but it's a lie. In winforms, yes. WPF sucks, and it's just unavoidable that you need to do it yourself. In fact, I found recently that running 20 odd video thumbnails in repeat mode, never reloading them, would cause a memory crash pretty quick. It's a joke.
GC.Collect();
GC.WaitForPendingFinalizers();
SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
That's the magic code that I use. Without it, all my WPF apps would fail, for memory issues.
Christian Graus
Driven to the arms of OSX by Vista.
"I am new to programming world. I have been learning c# for about past four weeks. I am quite acquainted with the fundamentals of c#. Now I have to work on a project which converts given flat files to XML using the XML serialization method" - SK64 ( but the forums have stuff like this posted every day )
|
|
|
|
|
Christian Graus wrote: I am CG.
heh heh ...
Christian Graus wrote: I think you want to force GC. Doing so, can make the number in the task manager lower, and while it's not accurate, WPF is also crap at this, you get no dispose methods and if you swap a lot of images, memory will leak and your app will crash.
I've not seen any crashes as a result of this, nor has anyone reported crashes that might be related to memory but I think you might be right. I'm going to use PerfMon for a while and get a better idea of the real state of things with and without a forced GC.
Christian Graus wrote:
GC.Collect();
GC.WaitForPendingFinalizers();
SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
Will have a read up on this, Thanks GC ... oops!
|
|
|
|
|
Jammer wrote: Thanks GC ... oops!
*grin*
Yeah, if you're not moving a lot of video or images about, you should be fine, and I'd still advocate not calling this code until you need to. But, we were ready for beta and this code turned our crashing mess into an app that works.
Christian Graus
Driven to the arms of OSX by Vista.
"I am new to programming world. I have been learning c# for about past four weeks. I am quite acquainted with the fundamentals of c#. Now I have to work on a project which converts given flat files to XML using the XML serialization method" - SK64 ( but the forums have stuff like this posted every day )
|
|
|
|
|
Christian Graus wrote: Yeah, if you're not moving a lot of video or images about, you should be fine, and I'd still advocate not calling this code until you need to. But, we were ready for beta and this code turned our crashing mess into an app that works.
Gotcha.
I've worked on two WPF apps now and haven't seen anything like this. However, I've not been working with bitmaps or video, only audio.
Thanks for the code snippet.
Cheers,
|
|
|
|
|
I have three unknowns..
float hours;
float minutes;
float seconds;
I use them to draw correct pointers, which are refreshing all the time.
Now i want to know how to retrieve elapsed seconds, minutes and hours from timer start to write them in those three unknowns all the time for drawing??
|
|
|
|
|
see timespan
No trees were harmed in the sending of this message; however, a significant number of electrons were slightly inconvenienced.
This message is made of fully recyclable Zeros and Ones
|
|
|
|
|
I created a program to capture the video from 4 cameras, would have access to the live image from the Internet, What is the best way to view the Internet.
|
|
|
|
|
Alex_xso wrote: What is the best way to view the Internet
Open a web browser??
Alex_xso wrote: I created a program to capture the video from 4 cameras, would have access to the live image from the Internet,
Are you saying that you want to view the live video over the Internet?? In that case, you would need a streaming server, such a Microsoft's Windows Media Encoder[^]. Then you just provide links to the streams exposed by that server. The streams will open up in Media Player on the client machines.
|
|
|
|
|
Any example?
|
|
|
|
|
Don't have any. If you're using webcams, then you just need to setup the Media Exocding Server once. You wouldn't need a code example for something you do by hand.
|
|
|
|
|
How does one have mdichildren forms automatically sized to fit the parent form?
My situation is I may have 5 to 10 child form at once and I would like to see all at once.
I'm developing in C# in Visual Studio 2005
Any and all suggestion are appreciated.
Thanks
|
|
|
|
|
If I recall correctly you have to set a property in the parent called MdiLayout
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia) Why are you using VB6? Do you hate yourself? (Christian Graus)
|
|
|
|
|
Thanks,
I'm developing in VS2005 and it doesn't have that setting in the property view.
But that gives me an idea of what to look for and I'll still take any other answer
Thanks
|
|
|
|
|
I've just checked it and it's a method you need to call in the Parent, check the MdiLayout enum on MSDN for values.
this.LayoutMdi(MdiLayout.Cascade);
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia) Why are you using VB6? Do you hate yourself? (Christian Graus)
|
|
|
|
|
Let's say that you have a SortedList with the Key as a string and the Value as a struct. Also, the string Key is one of the data elements in the struct. Example:
using System;
using System.Collections.Generic;
namespace SortedListStructure
{
public struct Product
{
public string model;
public string description;
public int weight;
public int height;
public int width;
public int length;
};
class Program
{
static void Main(string[] args)
{
SortedList<string, Product> sl = new SortedList<string, Product>();
Product test;
test.model = "1X-3PA2Q94";
test.description = "Tractor Motor Sensor";
test.weight = 3;
test.height = 3;
test.width = 3;
test.length = 3;
sl.Add(test.model, test);
string m = test.model;
if (sl.ContainsKey(m))
{
Console.WriteLine("Description: {0}, Weight: {1}", sl[m].description, sl[m].weight);
}
else
{
Console.WriteLine("{0} not found", m);
}
Console.ReadLine();
}
}
}
While this works, the model is stored twice (I think? Is it?), once for the Key and once as one of the elements of the Product Value. One way to eliminate this redundancy would be to leave model out of the Product struct, but assume that this is not preferable. What is the most efficient approach when the Key is part of the Value?
|
|
|
|
|
Yes, the model is stored twice. But I think that is right and proper. I would not be happy removing "model" from "Product" as it is obviously a proper part of the data. Equally, it is a very sensible key for your sorted list.
You could save space (and maybe some processing time, but I doubt it) by using the hash value of the model string as the key, but then it is unlikely that the sort order would be the same. I assume you are using a SortedList because you want to iterate in model order - so the model itself has to be the key.
I would live with this. Removing "model" from "Product" means that that infromation is incomplete when processing in methods that don't know about your list.
No trees were harmed in the sending of this message; however, a significant number of electrons were slightly inconvenienced.
This message is made of fully recyclable Zeros and Ones
|
|
|
|
|
Yes, removing model from Product should be considered off the table. I was just wondering (purely hypothetical ) if there was a more elegant solution in which rather than having two separate lists of models, if somehow the Key referenced the model within product. I don't know if this is actually worth the trouble or even possible. It is not necessary to work but would be nice in terms of memory overhead. You could imagine a scaled up version of this problem in which the Key itself is a big complex struct or object and the Value is an even bigger struct or object that has the Key as one of its data elements (don't know how often this would actually come up since big numbers can index anything).
|
|
|
|
|
Yes, when it gets scaled up it is a problem. I think then that you have to come up with a hashing scheme which preserves your sort order, and use that as the key instead. The only other way I can think of immediately is to use an unsorted list, and sort it by model. Yeuch.
No trees were harmed in the sending of this message; however, a significant number of electrons were slightly inconvenienced.
This message is made of fully recyclable Zeros and Ones
|
|
|
|
|