16,018,805 members
Sign in
Sign in
Email
Password
Forgot your password?
Sign in with
home
articles
Browse Topics
>
Latest Articles
Top Articles
Posting/Update Guidelines
Article Help Forum
Submit an article or tip
Import GitHub Project
Import your Blog
quick answers
Q&A
Ask a Question
View Unanswered Questions
View All Questions
View C# questions
View C++ questions
View Visual Basic questions
View Javascript questions
View .NET questions
discussions
forums
CodeProject.AI Server
All Message Boards...
Application Lifecycle
>
Running a Business
Sales / Marketing
Collaboration / Beta Testing
Work Issues
Design and Architecture
Artificial Intelligence
ASP.NET
JavaScript
Internet of Things
C / C++ / MFC
>
ATL / WTL / STL
Managed C++/CLI
C#
Free Tools
Objective-C and Swift
Database
Hardware & Devices
>
System Admin
Hosting and Servers
Java
Linux Programming
Python
.NET (Core and Framework)
Android
iOS
Mobile
WPF
Visual Basic
Web Development
Site Bugs / Suggestions
Spam and Abuse Watch
features
features
Competitions
News
The Insider Newsletter
The Daily Build Newsletter
Newsletter archive
Surveys
CodeProject Stuff
community
lounge
Who's Who
Most Valuable Professionals
The Lounge
The CodeProject Blog
Where I Am: Member Photos
The Insider News
The Weird & The Wonderful
help
?
What is 'CodeProject'?
General FAQ
Ask a Question
Bugs and Suggestions
Article Help Forum
About Us
Search within:
Articles
Quick Answers
Messages
Comments by Daniel Grunwald (Top 9 by date)
Daniel Grunwald
23-Apr-11 17:19pm
View
This only applies to System.Threading.Timer. The other timers keep themselves alive until explicitly stopped.
Daniel Grunwald
23-Apr-11 17:18pm
View
The reference chain here is actually:
static list of timer callbacks (within .NET runtime) => new System.Threading.TimerCallback(...) => mtd.TimerCall(o){} => mtd => m_timer
If the timer would get garbage collected, it would deregister the callback from the static list. But it can't get garbage collected, since it still is reachable from a GC root. The GC can't look into finalizers to see that they would remove the last remaining reference.
So in a sense, this is a "cycle" that the GC can't deal with - but that's because the GC can't look into the future to see that if it collected an object that is still reachable, it would become unreachable.
But your solution reads as if the GC couldn't deal with cycles of references - that's giving the wrong impression, as the GC can handle those fine. One only needs to be aware that the whole cycle will live as long as the longest-lived object within the cycle.
Daniel Grunwald
23-Apr-11 17:03pm
View
Yes, it depends on the timer implementation. System.Threading.Timer in .NET 4.0 indeed looks like it keeps only the delegate alive, so breaking the reference chain from the delegate to the timer is sufficient to get the timer object collected (which will stop the timer in its finalizer).
However, System.Timers.Timer and System.Windows.Forms.Timer do keep themselves alive, so those need to be stopped explicitly.
Daniel Grunwald
23-Apr-11 12:07pm
View
A System.Threading.Timer starts automatically when the constructor is called.
If you add a "m_timer.Start()" call to your WinForms code, you'll find that the same memory leak will occur.
Daniel Grunwald
23-Apr-11 11:56am
View
The GC can handle circular references just fine, even with events and delegates.
The "event problem" only occurs when you have a long-lived object as events source, and a short-lived object as event handler: the delegate will keep the event handler alive as long as the event source lives.
In the worst case (event source lives forever, e.g. static event), the event handlers will never be garbage collected.
However, if the event source has a short lifetime, you do not need to unregister event handlers.
Daniel Grunwald
26-Nov-10 15:17pm
View
To clarify: "almost always" means "always except in a weird case related to COM interop". There's no way "new" returns null in pure C# code.
Daniel Grunwald
28-Oct-10 16:27pm
View
This explanation is incorrect.
The number is generated at COMPILE TIME.
Both List<string> and List<int> will use the class List`1. The `1 is simply appended by the compiler to disambiguate the class name (because C# allows having both List<T> and List<T,S> in the same namespace). It merely indicates the number of type parameters.
Daniel Grunwald
28-Oct-10 16:26pm
View
This explanation is incorrect.
The number is generated at COMPILE TIME.
Both List<string> and List<int> will use the class List`1. The `1 is simply appended by the compiler to disambiguate the class name (because C# allows having both List<t> and List<t,s> in the same namespace)
Daniel Grunwald
9-Aug-10 16:45pm
View
The Length property restricts the size to 2147483647 characters. .NET strings are stored as Unicode (UTF-16), so the maximum size is about 4 GB.
Of course, there may be other restrictions in the .NET runtime that prevent objects from being more than 2 GB (I think even the 64-bit .NET runtime has this restriction), so the actual limit may be a lot lower than that.
In my experience, anything larger than 200M characters and you're very likely to run into OutOfMemoryExceptions.
Show More