Hi again, i've implemeted the Dispose method on the conection object and it's seems to be the solution, first close, then dispose.
I also made some changes, before the Windows Service starts a mini app than register the remote object in a tcp channel, now the Windows services does all the work, and no extra app is needed, so, the solution copuld be bay one of thos changes or a combination.
Actually, you're looking at two different things. Visual Studio Online is not the Visual Studio IDE in the cloud. There is one feature of VSO that does enable you to edit code in the cloud, but it's only for websites deployed to Azure. See: Visual Studio Online "Monaco" videos on Channel 9.
Visual Studio Online is essentially a cloud implementation of Team Foundation Server with some additional cloud-based functionality. You should go ahead and create a free Visual Studio Online Basic account. That'll give you a place in the cloud for online source control. As you learn to code, you should also learn how to work with source control.
Express for Windows Desktop is the IDE heir to what was once Visual Basic Express, Visual C# Express, and Visual C++ Express. All three of those products (2010 era) are now what comprises Express for Windows Desktop. It's the best starting point for learning to code with any of those languages, and it connects to Visual Studio Online. For ASP.NET development, you'll need a separate Express product: Express for Web.
Agree with others. Go with Visual Studio Express. If you need cross platform option(some people use VMs to run other OS), use MonoDevelop[^]. FYI one more open source IDE SharpDevelop[^] there as an alternative.
Hey, all. Been after this one a few days and it's driving me crazy. I've refactored several times based on information I've found on the net (i.e. event handlers, circular references, etc) but I'm just not getting anywhere.
What I have is a generic hierarchical data structure that is distributed over a LAN via TCP. The concept was that I wanted to be able to share variables between applications over networked machines using a common protocol. The problem is whenever I run the thing and watch the process with Process Explorer, I can see a steady increase in Physical Memory usage (WS Private). I have a test application that accesses the nodes in the tree several times a second and can watch it climb (app consumes about 50 MB of memory when idle and then climbs at about 300 K per second). By playing around and commenting/uncommenting various blocks of code, I've narrowed the problem down to whenever the nodes in the tree are being accessed. At first I was certain that the problem was in the implementation of my object hierarchy because I had circular references (children had a reference to their parents) and figured that was messing up GC. But then I redid the implementation to remove that relationship and it's still happening. This is really driving me nuts.
Here's some (abridged) code. I can provide more if needed but don't want this to turn into a novel outright.
First, the object hierarchy:
Starts with a MustInherit base class: Node
Node is just a basic node in the tree. Everything that lives in the tree must inherit from this class.
Inherits from Node. It has an internal sortable dynamic list of Node instances and includes methods necessary to traverse that list (HasChildren, etc).
Inherits from ContainerNode. A Cluster is a collection of related nodes. A Cluster is the top most object in the tree. A Cluster contains a list of Groups and DataNodes.
Inherits from ContainerNode. A Group is a collection of related nodes within a Cluster. A Group contains more Groups and DataNodes.
Inherits from Node. A DataNode is a variable "leaf" item on the tree. It can be any kind of basic data type (string, integer, etc, etc).
The whole tree is accessed through a class called Agent. The Agent provides the methods necessary to add and remove nodes and set their values. It also sends changes in the tree out to the network and receives requests from connected clients over the network to modify the tree.
Nodes on the tree each have a signature, which looks pretty similar to a directory path in Linux (/Cluster/Group/Group/DataNode). I don't deal with relative paths.
So after a bunch of screwing around I've traced the problem down to whenever I access a node on the tree. Up at the App level, I have the following:
This corresponds to a property in a class called Service, which exposes the Agent and everything else to client applications (this whole thing is packed into a class library).
PublicProperty NodeValue(ByVal Path AsString) AsObjectGetReturn m_Agent.NodeValue(Path)
EndGetSet(ByVal value AsObject)
m_Agent.NodeValue(Path) = value
Within Agent, there is the following:
PublicProperty NodeValue(ByVal Path AsString) AsObjectGetTryReturnDirectCast(Me.GetNode(Path), Tree.DataNode).Value
Catch ex As Exception
ReturnNothingEndTryEndGetSet(ByVal value AsObject)
TryDim N As DataNode = DirectCast(Me.GetNode(Path), Tree.DataNode)
If (N IsNotNothing) ThenIf (N.NodeVal <> value) Then
N.NodeVal = value
If (Me.SuppressEvents = False) Then
EndIfEndIfEndIfCatch ex As Exception
GetNode does this:
PublicFunction GetNode(ByVal Path AsString) As Node
If (m_Nodes.IsEmpty) ThenReturnNothingEndIfIf (String.IsNullOrEmpty(Path)) ThenReturnNothingIf (Path.Equals("/")) Then
EndIfIf (Path.Substring(0, 1).Equals("/")) ThenReturn AbsolutePath(Path)
EndIfReturnNothingEndFunctionPrivateFunction AbsolutePath(ByVal Path AsString) As Node
Path = Path.TrimStart("/")
Dim Data() AsString = Path.Split("/")
If (Data.Length > 0) ThenDim Index AsInteger = m_Nodes.GetItemIndex(New SearchNode(Data(0)))
AbsolutePath = m_Nodes.AtIndex(Index)
If ((AbsolutePath IsNotNothing) And (Data.Length > 1)) ThenFor X AsInteger = 1To Data.Length - 1If (AbsolutePath IsNotNothing) ThenIf (AbsolutePath.HasChildren) Then
AbsolutePath = DirectCast(AbsolutePath, ContainerNode).Child(Data(X))
Now, through testing, I've found that calling GetNode is enough to make the memory leak occur. That means no events firing and nothing else special, just a simple GetNode, which returns the Node instance back to the caller.
It seems to me that this should be something that the language should be able to handle, so I'm either missing something fundamental or I'm nowhere near as knowledgeable as I'd like to believe.
I greatly appreciate any help, hints, or insight you can provide.
You're either generating more objects (and faster) than the GC can clean up and manage, or you're keeping a reference to those objects somewhere. Is there a custom paint-handler somewhere in the application?
Put the mouse on a suspicious class, and hit Shift-F12. That should give you a list of all the places where the class is being used.
Another quick and dirty way would be to implement IDisposable, and have the class log a line whenever an object is created (in the constructor) and when it is disposed of.
The best way would be to use a (commercial) memory-profiler. You'll get a nice graphic showing what's been allocated at what point. Microsoft also provides a tool of course, with their "howto" here[^].
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
I was fairly certain I had all the events issues sorted but perhaps not. I'll go through and take a closer look at the difference classes involved (using your shift-f12 suggestion) and see if I can find anything likely.
It's important to note that before doing any of the above, I had already traced down the sections of code in my program that were creating the link. There are various ways to do this. For me, I had at least a general idea of the method calls causing the problem, so I began systematically commenting out blocks of code and re-running the app while watching Process Explorer. I eventually got to a point where the leak stopped occurring, at which point it became clear to me where this was happening. So lesson 1, it turns out that finding the leak can be pretty easy; fixing it might be not as straight forward.
I used sos.dll to dump my heap memory while running the program to see exactly what it was that was causing the usage to blow up. I'll note here that my platform is Win7 64 bit and my program was configured to target any CPU, which caused issues when I tried to click the "Enable unmanaged code debugging" check box in the project properties window. I had to set the target CPU to x86 to get that to work. Everything else as presented in the article I linked above concerning sos.dll worked as described (I used !dumpheap, !gcroot, etc commands from the immediate window in my case).
What I found was that I had a large number of System.WeakReference instances hanging around and not getting cleaned up. You can see where I discuss this earlier in this thread. From what I've read on the net, it seems that the biggest cause of this happening is when you instantiate object that add event handlers and then don't remove those handlers properly later when you're done with the object. I thought that this wasn't a problem in my code because I had rewritten it to minimize events and handlers as much as possible.
Even so, it turns out that I'm an idiot.
A long time ago, I wrote a generic interface for my class library that describes a basic set of debugging/logging events and handlers for any class that I wanted to be able to write information to my own home-rolled logging system. Very simple stuff; in a nutshell:
Event InfoMessage(ByVal e As EventInfo)
Sub OnInfo(ByVal Message AsString)
Sub OnInfo(ByVal e As EventInfo)
Event Err(ByVal e As EventErr)
Sub OnErr(ByVal Description AsString)
Sub OnErr(ByVal e As EventErr)
Event Exception(ByVal e As EventBaseException)
Sub OnException(ByVal e As System.Exception)
Sub OnException(ByVal e As EventBaseException)
Event Debug(ByVal e As EventDebug)
Sub OnDebug(ByVal Message AsString)
Sub OnDebug(ByVal e As EventDebug)
Event Warning(ByVal e As EventWarning)
Sub OnWarn(ByVal Message AsString)
Sub OnWarn(ByVal e As EventWarning)
This works out fine when you have a few root classes that implement it that you expect to live throughout the life of the program. But when I wrote this, it worked out so well for me and made my life so easy that it became common practice for my to implement this in any new class I created.
So, I had some very low level items in the object hierarchy (node, signatures, etc, etc) all inheriting from a single master object: SortElement. SortElement is a custom object I wrote that anything can inherit from and become something that can be sorted rapidly in a Vector class that I wrote at some point. Guess what interface SortElement implements? Yep: CoreEvents. Duh.
So I went back and cleaned that up and remove that interface from anything that doesn't need it or shouldn't get it (specifically, objects likely to be instantiated and then dumped on a moment's notice like list nodes or helper classes like NodeSignature.
I wrapped all that up and rebuilt and was met with an app that consumes no more than 35 MB of memory while running (before it was consuming something like 300 K per second perpetually until running into an OOM exception).
I also find it relevant to note that I did not have to rebuild the application under Release config (rather than Debug) as many forum posts out there suggest (I'm building against .net 3.5).
Anyway, hope some folks find this helpful. I'm actually rather thankful I came across this; it was maddening but well worth what I learned when dealing with it.
Last Visit: 31-Dec-99 18:00 Last Update: 27-May-17 2:28