Simple object garbage recycling frame for Delphi

zhaozj2021-02-11  177

1st origin

1.1 I am an error program

Program Name: The pressure test tool for call processing modules is divided into client and server.

Development Tools: DELHPI 5

Related Art: The client simulates the processes such as the dial-in, buttons, waiting, hanging machines of a group of telephones by establishing a Socket connection with the server. The server is preproces the socket event and the received packet and converted to an abstract call model data, and then sends it to the upper layer of call processing module. Since the call processing module is hardware-independent (unrelated to the voice board, the switch type), this pressure test tool can be more realistic to simulate a massive call to achieve the logical correctness of the test call processing module program and its performance .

Due to certain considerations in the design of the system, the test tool is implemented as two programs of the client and the server, and communicates with Socket. Now I want to come, it is better to integrate into a program to achieve more simple - but it is also because two programs are used to implement some problems, and therefore introduce a simple garbage collection framework.

1.2 problem

During the use of test tools, we found that when the amount of calls is huge and the test tool moves frequently, the system appears below:

n Access Address Violation, the code address is located near $ 0046FC80, and the access address is more than $ 00000028.

n An EinValidcast error indicating that an address is incorrectly converted to an address class (using an AS key).

There are many assertions in the n program fail, and there are many references that have been designed to be destroyed.

After carefully checking the process, I still think that all this is simple! Moreover, the program used to test the test of other programs, but there is such a problem, almost almost selfless!

In order to save your reputation, I have to be a heavy tracking of errors and disclose the problem!

2 solution

2.1 check error

In fact, the problem is still relatively smooth.

By looking through the program's call stack, the discovery program is always stayed in the process of sending a socket packet before an error. Next, further through single-step tracking, the Socket detects the opponent connection in the process of sending the packet, and the ONDisconnect event is triggered. And I was in accordance with the Socket handle delivered in the IOSCONNECT event of Serversocket, and found the corresponding object to be destroyed.

The code I am in the last ondisconnect event in Serversocket is as follows:

Procedure TXXXX.ServerClientDisconnect (Sender: Tobject) (SENDER: TOBJECT)

Socket: tcustomwinsocket;

Begin

...

Flines.destroylineBysocket (Socket); // is this sentence, released in an inappropriate time

...

END;

The problem is this.

For example, there is a code in a certain process (the front is a line number):

1 fline.dosomething;

2 fline.sendsocketdata;

3 fline.dootherth;

Among them, FLINE is an object representing all the calls. This object is within the inside of this object. A TCUSTOMWInsocket pointer is referenced. SendsocketData is sent using this socket for data transmission.

FLINES is an example of the container class of the TLINE object.

It is not difficult to interpret the aforementioned mistakes:

1. Since the Socket connection disconnecting of line 2 causes the FLINE object to release, the line 3 accesses dootherthings almost inevitably cause access to the address. Due to the object of the line 2 destroyed, the code similar to "Object As TLINE" in the program causes a second type of error;

3. Since the object is destroyed in advance, the post-treatment work is not in place, resulting in a third type of error;

2.2 Solution

After understanding the reason, the problem solves more.

The above problem is not more than two options:

First, determine if the instance is present

After dootherthings, it is determined whether the FLINE object is still in FLINES, and if so, continues processing, otherwise end processing;

Second, delay the destruction of the FLINE object

In Serversocket's OnDisconnect, the FLINE object is thrown into the trash, and then destroyed when it is mature.

Considering the amount of code to be changed by the program, the code code is not very beautiful, so it is decided to use the second plan to solve the problem. The main point of the program is to select the appropriate timing to really destroy the object. And for this, the problem is not large, just select the first link for processing the message in the message loop to recover. Because in the subsequent processing link, it is inevitable to ensure that FLINE is still valid.

3 Simple Object Garbage Recycling Framework (ungarbagcollector)

3.1 Overview

Simple garbage collection is very simple:

n Use TTHReadList to support thread and access, and save the object pointer to be recovered;

n Provide a PUT method to save the object to be recycled;

n Provide Recycle method for real recycling (because all objects are derived from TOBJECT).

3.2 Implementing code

Unit Untgarbagcollector;

Interface

Uses

Classes;

Type

Tgarbagcollector = Class (TOBJECT)

Private

Flist: tthreadlist;

public

Constructor crete;

DESTRUCTOR DESTROY; OVERRIDE;

Procedure Put (const AObject: TOBJECT);

Procedure Recycle (Const Maxcount: Integer);

END;

Function Garbagcollector: Tgarbagcollector;

IMPLEMentation

VAR

_Garbagcollector: Tgarbagcollector;

Function Garbagcollector: Tgarbagcollector;

Begin

IF not assigned (_garbagcollector) THEN

_Garbagcollector: = tgarbagcollector.create;

Result: = _garbagcollector;

END;

{Tgarbagcollect}

Constructor tgarbagcollector.create;

Begin

FList: = tthreadlist.create;

END;

Destructor Tgarbagcollector.destroy;

Begin

Try

Recycle (flist.locklist.count);

Finally

Flist.unlocklist;

END;

FList.Free;

End; procedure tgarbagcollector.put (const AObject: TOBJECT);

Begin

Try

Flist.lockList.Add (AObject);

Finally

Flist.unlocklist;

END;

END;

Procedure Tgarbagcollector.Recycle (const maxcount: integer);

VAR

I: integer;

Alist: TLIST;

Begin

Alist: = flist.locklist;

Try

I: = 0;

While (alist.count> 0) and (i

Begin

TOBJECT (alist.last) .free;

Alist.delete (alist.count - 1);

INC (I);

END;

Finally

Flist.unlocklist;

END;

END;

INITIALIZATION

Finalization

IF assigned (_garbagcollector) THEN

_Garbagcollector.free;

End.

3.3 Example of use

After reference to the undgarbagcollector unit, you can use GarbagCollector to destroy and recycle the object.

N destroyed

AObject: = TOBJECT.CREATE;

Garbagcollector.put (AObject);

n recycle

The Recycle method can be called at timer, thread, and other occasions.

Maxcount is used to control the parameters of each destruction, mainly afraid that there are too many CPUs that occupy too much.

(Suddenly discovered can also be extended to limit the time to destroy, such as N milliseconds that do not exceed each destruction).

3.4 Use occasions

In this case, garbage recovery technology is introduced in order to prevent access to access violations in order to prevent the subject.

In other occasions, this technology can also be introduced in order to improve the subjectivity of certain programs. For example, the program that completes some specific tasks, the temporary object is generated during the processing, and the destruction of these objects is time consuming. Therefore, in order to end the task as early as possible, these temporary objects can be saved to the busbar. The CPU is completely destroyed when the CPU is complete after the job (task) is complete, and the temporary object is really destroyed. The true meaning of this approach is to deliver objects with some systems, and reuse objects to improve performance.

Culture

转载请注明原文地址:https://www.9cbs.com/read-5299.html

New Post(0)