views:

831

answers:

6

When we created our program, it closed properly under XP, but under Vista, even though the program is closed, the process is often still running until I open task manager and manually kill the process.

Any suggestions on how to make sure this is closed when we close the program? What a pain.

Mark Gundy www.magchat.com

A: 

What do you call to close your program? Try using

Application.Terminate;

To force all forms to close and the process to exit.

Mark Pim
A: 

... and if you need to close single form, then use:

Form.Close;
  • GUI AND HANDLER DELETED. Reference and some parts of memory is left to provide access to variables, constants, etc.

If you need to hide ( something like Minimize, only GUI is cleared ) form, then:

Form.Hide;
  • GUI is cleared, leaving internal resources untoauched ( reference, handler, memory )

If form is dynamic ( created at runetime ), then use:

Form.Destroy;
  • ALL RESOURCES WILL BE CLEARED FROM MEMORY, leaving reference and handlers attached so you could access its location in memory.

If form is dynamic and you will not use it for the same interface, then:

Form.Free;
  • ALL RESOURCES, REFERENCES, HANDLERS ARE DELETED. I recommend to use this to VCL TComponent class, not for TForm class.

Also, there is Form.FreeAndNill, but my guess that it deleted all memory and loaded handlers, only allowing to use same memory space in the same interface again... (I might be wrong though).

P.S. I hope I am not writing wrong things as the last time I read the theory was a long, long time ago... and it was about Destructor DESTROY in general ...

P.P.S ALSO PLEASE BE CAREFUL if you're writing a Vista-ready app - that it includes UAC Handling with manifests / runtime code and SuperBar compatibility requirement. Also Aero requires some additional megabytes to output file due its Aero feature ... :P

HX_unbanned
-1 for a mixed bag of half-truths and factual errors, and for the biggest part of the answer having nothing to do with the question.
mghie
A: 

It probably means you have some memory leak - some resource is not released.

If your application instantiates COM objects, check that you properly close them.

If you use older version of Delphi, you can try to locate possible memory leaks with FastMM

Edit, examples as requested:

I had two situations where application sometimes would stay resident in memory after exit. Both applications would disappear from taskbar, but they would be still active - visible in task manager. Both applications were created with Delphi 7.

  1. First application has one main window with panel in which ather forms are embedded. Each form is standard TForm. Each form is created first time user requests it. Everything worked without problems in test environment, but users reported that from time to time, application would remain in memory, usually after longer usage - when user displayed almost all of the forms in application. I could not replicate this behavior while testing. That was first time I found out about FastMM. When I first run application with FastMM, it reported that some of forms embedded in main form were not released. This version was tested at user site and it turned out that 2 forms that have lots of data aware components would hang up and prevent application from exiting. When I added code that makes sure that all created forms are released before main form, application never hung up on exit.

  2. Second example is application that uses COM to activate GIS editor (Geomedia) to manipulate some map data. I imported type libraries and created Delphi wrapper object. Some of created objects were not freed when application ends. Application icon disappeared from task bar, but application and GIS editor were still active and visible in task manager. Again, it did not happen every time application run. I included FastMM in application and it reported that some objects were not freed. I made sure that every created object gets freed and after that application did not hang on exit any more.

zendar
FastMM units is compatible from Delphi 6 and above ;) Different question is about its pre-requisties and compatability. It s been half year when I last time used Fast MM 4 ...
HX_unbanned
I think it works D6-D2007, so he can try unless he is on D2009.
zendar
Please describe in more detail the circumstances under which a memory leak would cause a program to hang.
Rob Kennedy
+3  A: 

Are you using multiple threads? If one of them can't terminate for some reason, it'll hang the cleanup process.

Mason Wheeler
Are you sure? When a program calls ExitProcess, all threads are terminated immediately. Where in the Delphi RTL does it wait for threads to finish before calling ExitProcess?
Rob Kennedy
Not sure where it is in the Delphi RTL, but I know it's been a problem for me in the past...
Mason Wheeler
@Rob: TThread.Destroy does a Waitfor. If you free your threads from your mainthread at closing time, and their execute is in an infinite loop for whatever reason, your program will not close. ExitProces will never be reached.
Paul-Jan
+3  A: 

The short answer is that you have a bug in your application. So, have you tried debugging it?

If you have the Delphi IDE installed on Vista, run the app from the IDE and break it when it 'hangs'. Chances are that you'll have a thread that hasn't terminated itself, and the VCL is waiting for it to finish.

If you don't have the IDE installed on vista, you can probably use the remote debugger, but I'm not familiar with this.

Roddy
AFAIK, Process cannnot kill itself / thread cannot terminate itself. In Vista, this IS because people dont now excatly how UAC will behaive. Currently best solution for a bit safer Vista operation is tu use FastMM unit and manifest that lets app to run with full privilegies... The process / thread handling still is the same as Delphi is still the same, right? ;)
HX_unbanned
+1 for suggesting the debugger. (Such a foreign concept these days, it seems.) Rather than debugging the whole thing, it might be easier to reproduce if he lets it hang first, then "attaches" to the process afterward. And HX, processes and threads *can* terminate themselves. That's the *usual* case.
Rob Kennedy
@HX_unbanned: How does forcing elevated privileges on Vista make for a safer operation??? If anything the opposite is true. And the cure for people not knowing how UAC behaves would be for them to read about UAC and experiment with their program within a limited account on a Vista machine.
mghie
@HX : Rob is right - terminating a thread safely always involves somehow "asking" the thread to shut itself down. If you ever use the *TerminateThread* API call to kill a thread, you have a disaster waiting to happen.
Roddy
Rob, I meant just like that ... like having AI. If it is part of algorythm, sequence or procedural action., then yes, they can, of course. mghie - I've tested UAC and I can say that UAC is one crazy feature - and - I advised this in the case question creator is skilled programmer - than it should not be big problem ... only limitation is time. Yes, it seems like I did formulate my answer a bit strange. My bad.
HX_unbanned
+4  A: 

The debugger will be your friend here. Step through the shutdown until you get stuck. That'll be the best bet.

But... assuming for some reason the debugger is affecting the behaviour, or can't be used for some other reason:

  • A few earlier replies suggest using FastMM. This has been the default memory manager for delphi since D2006. You can try flipping on the options to report memory leaks... but that'll only work after you've finished shutting down the process, which is what isn't working. :) So I doubt it will help you much in this case. The full version of FastMM, as opposed to the standard one packaged with delphi, might have some other helpful features... But I can't recall any that would help here.

  • To inspect your app while it's stuck, you could try the sysinternals tools, like Process Explorer & Process Monitor. Process Monitor may show you if it's choking on any ACCESS_DENIED errors, etc, and the stack trace at the time of the error. Process Explorer could be especially useful, by listing all the handles your process is still holding open, and allowing you to view the stack of all its living threads. A familiar function or two, in the stack traces of any hung threads, may send you hunting in the right area.

otherchirps
Well, a particularly handy feature of the full version of FastMM is the FullDebugMode switch. If the cause of the issue is memory corruption, it might trigger the problem _early_ and provide a little more info about what is going on.
Paul-Jan
Ah - yep, of course. A nice early-crashing mode. Definitely a helpful switch that slipped my mind. Thanks.
otherchirps