Simple Object garbage collection framework for Delphi

Source: Internet
Author: User

I accidentally thought that there was no garbage collection mechanism in Delphi, so I wanted to see if anyone had done this.

Later I found this article and wrote it very well. I borrowed it for reference, but unfortunately I don't know the author.

From: http://developer.51cto.com/art/200510/7129.htm


1 origin
1.1 one of my error programs

Name: The stress testing tool of the call processing module, which is divided into the client and server.
Development Tool: delhpi 5
Related Technologies: the client establishes a socket connection with the server to simulate the dial-in, press-down, wait, and hanging processes of a group of telephones. The server processes socket events and received packets, converts them to abstract call model data, and sends the data to the upper-layer call processing module. Because the call processing module is hardware independent (it has nothing to do with the Voice board and switch type), this stress testing tool can be used to simulate massive calls in a more realistic manner, to test the logic correctness and performance of the Call Processing Module Program.
Due to some considerations during system design, the test tool is implemented in two programs: client and server, and socket is used for communication. Now, it is better to integrate into a program for implementation-but it is just because two programs are used for implementation that raises some of the following problems, A simple garbage collection framework is introduced.
1.2 Questions
During the use of the test tool, we found that the following error occurs when the volume of the test tool is large and the operation of the test tool is frequent:

  • Access address error (eaccessviolation). The Code address is located near $0046fc80, And the access address is mostly $00000028.
  • The einvalidcast error occurs. This error indicates that an error occurred while converting the class type of an address (The as keyword is used ).
  • Multiple assertions in the program fail, and many references to destroyed objects occur.

After carefully checking the program, I still think it's incredible! Moreover, the programs originally used to test other programs have such problems, which almost leaves me alone!
In order to save my reputation, I had to stay calm and track errors carefully to solve the problem!

2 solution
2.1 The problem is still solved smoothly.
By viewing the call stack of the program, it is found that the program always stays in the process of sending socket data packets before an error occurs. Next, through the single-step tracking, it is found that during the packet sending process, the socket detects that the peer connection has been disconnected, and the ondisconnect event is triggered. In the ondisconnect event of serversocket, I found the corresponding object to destroy it based on the passed socket handle.
The code in my ondisconnect event in serversocket is as follows:

Procedure txxxx. serverclientdisconnect (Sender: tobject; socket: tcustomwinsocket); begin... Flines. destroylinebysocket (socket); // exactly this sentence, releasing the object at an inappropriate time... End;

This is the case.
For example, the following code is available in a process:

FLine.DoSomething;FLine.SendSocketData;FLine.DoOtherThings;

Fline indicates the object of a single call. This object references a tcustomwinsocket pointer. Sendsocketdata uses this socket to send data.
Flines is an instance of the container class of the tline object.
It is not difficult to interpret the aforementioned errors:

 

  1. The fline object is released because the socket connection in Row 2 is disconnected. Therefore, access to dootherthings in Row 3 will almost inevitably cause an access address error;
  2. Because the object in line 2 is destroyed, the code similar to "object as tline" in the program causes the second type of error;
  3. The third type of errors is caused by the fact that the objects are destroyed in advance and the aftermath are not handled properly;

2.2 Solutions
After understanding the cause, it is much easier to solve the problem.
There are two solutions to the above problems:
1. determine whether an instance exists
After dootherthings, determine whether the fline object is still in flines. If so, continue processing; otherwise, end processing;
2. delayed destruction of fline objects
In ondisconnect of serversocket, The fline object is thrown into the garbage pool and destroyed when the time is ripe.
Considering that solution 1 has a large amount of code to be modified, and the code of this solution is not very elegant, it is decided to adopt solution 2, that is, introducing the garbage collection mechanism to solve the problem. Solution 2 focuses on selecting the right time to destroy objects. This is not a problem. You only need to select the first step of Message Processing in the message loop to recycle the message. This is because, in subsequent processes, it is necessary to ensure that the fline is still valid.

3. Simple Object garbage collection framework (untgarbagcollector)
3.1 Summary simple garbage collection is very simple:

  • Use tthreadlist to support concurrent thread access and save the object pointer to be recycled;
  • Provides the PUT Method to save objects to be recycled;
  • Provides the recycle Method for real collection (because all objects are derived from tobject ).

3.2 Implementation Code unit untgarbagcollector;

 

interfaceusesClasses;typeTGarbagCollector = Class(TObject)privateFList: TThreadList;publicconstructor Create;destructor Destroy; override;procedure Put(const AObject: TObject);procedure Recycle(const MaxCount: Integer);end;function GarbagCollector: TGarbagCollector;implementationvar_GarbagCollector: TGarbagCollector;function GarbagCollector: TGarbagCollector;beginif not Assigned(_GarbagCollector) then_GarbagCollector := TGarbagCollector.Create;result := _GarbagCollector;end;{ TGarbagCollect }constructor TGarbagCollector.Create;beginFList := TThreadList.Create;end;destructor TGarbagCollector.Destroy;begintryRecycle(FList.LockList.Count);finallyFList.UnlockList;end;FList.Free;end;procedure TGarbagCollector.Put(const AObject: TObject);begintryFList.LockList.Add(AObject);finallyFList.UnlockList;end;end;procedure TGarbagCollector.Recycle(const MaxCount: Integer);varI: Integer;AList: TList;beginAList := FList.LockList;tryI := 0;while (AList.Count > 0) and (I < MaxCount) dobeginTObject(AList.Last).Free;AList.Delete(AList.Count - 1);Inc(I);end;finallyFList.UnlockList;end;end;initializationfinalizationif Assigned(_GarbagCollector) then_GarbagCollector.Free;end.

3.3 example
After referencing the untgarbagcollector unit, you can directly use garbagcollector to destroy and recycle objects.

  • Destroy
AObject := TObject.Create;GarbagCollector.Put(AObject);
  • Reclaim

You can call the recycle method on the timer, thread, and other occasions.
Maxcount is a parameter used to control the number of destroys at a time. It is mainly used to destroy too many CPU resources at a time.
(Sudden destruction can also be extended to a limited time, for example, the time consumed for each destruction cannot exceed n milliseconds ).
3.4 usage
In this case, the garbage collection technology is introduced to prevent access conflicts caused by premature destruction of objects.
In other cases, such as to improve the subjective performance of some programs, this technology can also be introduced. For example, a program that completes some specific tasks will generate temporary objects during the processing process, and it is time-consuming to destroy these objects. Therefore, to end the task as soon as possible, you can save these temporary objects to the garbage pool. When the job (task) is completed and the CPU is idle for a period of time, the temporary object is actually destroyed. The true meaning of this practice is to exchange space for time-the same way as some systems pre-create objects and reuse objects to improve performance.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.