Atmapuri posted this message in borland.public.delphi.non-technical about his obsersavtions on memory leaks in Delphi 2005. He also posted some steps to disable Together to make the memory leaks go away, and also some information on what could be affected by doing this. Obviously, do this at your own peril.
The 10,000 foot view highlights from his post:
The severity of the memory leaks is proportional
to size of the source file being edited.
To completely resolve them:
Remove or rename the following packages
to disable Together:
"tgide90.bpl"
"borland.studio.together.dll"
in the \Bin directory.
It is not sufficient to disable Together from the Project
menu!!! The memory leaks due to Together will
happen as soon as you use the code editor and while
the Delphi is starting.
And here is the list of things he thinks get affected when you do this:
It affects ECO II modeling in Delphi.NET and C#. ECO II will still
work, but modeling will not. If you use W32 only
I think you dont loose anything.
Check the original post out for more detailed techincal information. Great stuff, Atmapuri!
I was reviewing some multi-threaded code for a friend last night. The code was causing problems, especially on a multi-CPU machine. The code was using global variables and no synchronization to protect access. So I did some searching on google and found some very good primers on threading in Delphi.
Borland has started interviewing some R&D engineer, and is broadcasting the chats over the internet. You can hear the chats live, and even ask questions. Here is the schedule of chats. This page lists all of the chats, but keep an eye on EventCentral, Borland's new calendar program, for more information about the chats and other Borland-related events.
After the chat is over, Borland is making a transcript of the chat log and an audio replay of the chat available. So if you can't make one of the chats live, you can hear it later. Here is the list of available chats. Borland continually updates this page as more chat replays become available.
Here are the steps I use to debug an NT service that was created with Delphi 6. While this works for me, there may be room for optimization.
- Our applications differentiate between a service and server version by conditional define. If you do the same thing, be sure to remember to compile the server with your "SERVICE" directive in Project | Options
- In Project Options | Linker, check the options for "Inculde TD32 debug info" and "Include Remote Debug Symbols"
- Do a full build on the server
- Register and install the service (e.g. "mysrv /regserver" and "mysrv /install") . The regserver part is needed if your serivce is a COM service.
- Set breakpoints where you want them in the server code
- Open up the Services Control Panel applet
- Select the server in the applet, and press Start
- *VERY QUICKLY*, go back to Delphi and select Run | Attach Process, select the service executable (e.g. MySrv) and press Attach
- You may get a CPU view in the Delphi IDE at this point. If so, press F9 again.
- You should be able to run a client now and have the breakpoints be respected. You may be presented with the CPU view when the breakpoint is tripped. Just go to the source window, and everything should work as normal.
NOTE: The reason for the CPU view is due to a MS problem in ntdll.dll. For some reason, they shipped Win2k and above with a hard breakpoint in the file. I used this Delphi expert, and things worked much better. You may need this file in order to get debugging working. Then again, you might not. ;)
I've had limited experience using unit testing, but I have read a considerable amount on the subject - especially as it pertains to Java. Most of the time, I want to add unit testing, but it's always a hard sell to management. It's an even tougher sell to management when you come in to a project that has been selling. After all, "The product works fine. Sure, it may have some bugs, but we'll fix those in due time.". I come from a more proactive school of thought where I'd rather we find ways to prevent bugs in the first place, and have the code be maintainable enough to fix it when a bug does creep in.
That's where unit testing comes in. If you can find a way to automatically identify bugs before they get into your codebase, you're much better off. Additionally, writing unit tests typically results in writing more maintainable code. After all, I would hope that you wouldn't want to write one test case to exercise a 3,000 line function. :-(
All of the above is just an introduction to John Kaster's BDNTV episode on unit testing in Delphi 2005. Check it out. It's short, but still very informative.
I've been playing with AQTime for a little over 1 week now. All in all, I love it. My company bought 2 licenses because we saw the potential in the product.
Here are the things I like so far:
- Support. The people on their newsgroups are fantastic.
- The GUI. They make liberal use of DevExpress components throughout, and do so quite capably.
- The new Assistant window that helps guide you through the profiling process.
- The samples and documentation.
The things I don't like so far are greater - not necessarily in number, but in quality.
- Leaked Delphi objects are reported as "VCL native memory.N", where N is the number of VCL objects that have been created so far. AQTime 3 reported the actual object name here.
- If you use run-time packages (at least with Delphi 6), AQTime 4 won't show you any leak information. AQTime 3 showed me leak information without fail. According to Atanas, the next version of AQTime 4 should fix this problem.
- In AQTime 3, they used to have a profiler called Reference Count Profiler. This would help you identify bad AddRef/Release lifetimes. The
claim is that AQTime 4 can get by without this, but I'm not sold yet - especially given the first 2 points.
- I have a support issue open trying to get DCOM Server support done properly in AQTime 3.
Now, I realize that I'm just coming up to speed with this product, and this may very well be a case of RTFM and/or learning curve. I reserve the right to move things from the "like" to "don't like" category as I learn more about this very powerful product. But the bottom line is that, for
most of our profiling right now, we are using AQTime 3, as it seems a bit more capable than AQTime 4.
During my perusal of their newsgroup, I noticed a little tidbit that said something to the effect of: AQTime 4 is a new version of AQTime that
merges together the old Unmanaged profilers and the newer .NET profilers. During the effort to get AQTime 4 produced, they understandably looked for ways to improve the product. They probably shared new codebases, consolidated the list of profilers, etc. The combination of all these things means that I'm waiting for patches to AQTime 4 before I can use it to it's fullest extent. I know of Atanas' well-deseverd and excellent reputation in the Delphi community, so I'm not worried that I'll never get what I want. I just hope it's sooner rather than later.
Everything is set. Here is the information on the Delphi 2005 launch event in Milwaukee.
John Kaster will be presenting a free session on Delphi 2005. It will run from 6:00-8:00 pm on 12/21/04 at the Marriott West in Pewaukee. That page should get you there with only slight problems. For some unknown reason, the civil engineers in the area decided to rename a bunch of highways out here, so pay close attention to the orange signs under the exit signs. "Former Highway 164 North" is now Highway F North, I believe. Or, just pay attention and take Exit 295 (as they mention in the directions on the web page).
In addition to getting some great information, John will be bringing Christmas spirit with him, and act as Santa Claus for the evening. There will be free T-shirts and other goodies to give away, flyers and marketing materials on Delphi 2005, feedback forms to let Borland know what we think, rebate coupons good for 25% off Delphi 2005 purchases (must be present to receive one; they are time limited (no immediate details - John thought they might be good through the end of this month or next, and John also thought it covered up to 4 copies - read the form when you get there for the final word ), a drawing to give away a Delphi 2005 Architect, and depending on attendance, a drawing for 1 or more Delphi 2005 Pros. How's that for a run-on sentence?!?
I will be emailing everyone on my list with this same information. Feel free to email me if you need to change your RSVP, or if you know of anyone else who wants to show up. It looks like we're going to have a great turnout. Thanks everyone, and I look forward to seeing you all there!
Using DBX, we came across a bug where the values for the fields in the first record were not available in the OnCalcFields event. After doing some digging, I found that this was already reported as QC 1328. I noticed that the problem was marked as Fixed in Delphi 2005, and we are still using Delphi 6, so that would explain it.
I then went and modified my own test case, and the one reported in QC and noticed that both of these test cases still exhibited the problem in D2005. I talked to a couple of friends in Scotts Valley, and they confirmed the behavior as still being present in Win32 in D2005. So, it turns out that the fix only made it to the VCL.NET side of things. At least that source is similar enough to figure out what's going on.
The problem exists in TDataset.GetCalcFields. Take a look at the VCL.NET implementation in D2005 for the complete code. However, I still needed to get the fix into our codebase, and we won't be upgrading everything to D2005 for a little bit yet. We also can't just patch the VCL in the DB.pas unit since we are using runtime packages on our app servers in order to pass VCL components around.
With all of these requirements in place, I set out to create a descendant of TSQLQuery and override GetCalcFields. This turned out to be problematic, however, due to the fixed code's need to set the FEOF private variable in TDataset. I realized that the EOF property is read-only and that the backing field is private, so I used Hallvard's Hack #1. This works absolutely flawlessly, and I now have the fix isolated to one place so that when we upgrade to D2005, I can simply remove this new component in the handful of places that it gets used.
Here is the implementation code that I finally came up with:
type
TDatasetEx = class(TDataset)
published
property EOF;
end;
procedure TDRMSQLQuery.SetEOF(Value: boolean);
begin
PBoolean(Integer(Self) + (Integer(GetPropInfo(TDatasetEx, 'EOF').GetProc) and $00FFFFFF))^ := Value;
end;
{$WARNINGS OFF}
// We are guaranteed that the only time we both set and use eofBak is when
// State = dsInactive. Therefore, we don't care about the warning.
procedure TDRMSQLQuery.GetCalcFields(Buffer: PChar);
var
eofBak: Boolean;
begin
if (State = dsInactive) then
begin
eofBak := EOF;
SetEOF(False);
end;
try
inherited GetCalcFields(Buffer);
finally
if (State = dsInactive) then
SetEOF(eofBak);
end;
end;
Notes:
- I would fully expect that Borland will fix this fully in an upcoming D2005 patch.
- Thanks to Joerg and John (from Borland) for helping out with this one.
- The problem does not exist in the BDE, just DBX. I haven't checked other data access layers (ADO, IBX, DOA, etc.), but if they have the same problem, then you can use something like this technique to fix it for now. Since the true fix is in TDataset, all other implementations will be fixed automatically when that fix is rolled out.
|