Talking about the reference count

zhaozj2021-02-16  58

Talking about the reference count

Foreword

As a Delphi programmer, you don't have to look at this section, but if you want more about some COM internal technology, or if you can perform well between the object model and the reference model, the author wants you to take out. Sometimes I will see all the content, and the benefits will be obvious, you can freely use some techniques to solve the problem that makes your headache. Ok, continue our exchange today;

In the III of the Component Technology, we have introduced the interface (Interface). When we don't have in-depth implementation / efficiency / optimization of the interface, we know that they are indeed Programming is very helpful, we all know that each interface will maintain a global variable FREFCOUNT (this is the name of the variable in Object Pascal, if it is in C , it is m_cref), it is specifically used to control The life cycle of the interface, or the lifecycle of the component (component / interface is also life cycle), of course, we can also force the interface to give the value NIL can also release the interface, but that is unsafe or should not be recommended. . The reason why the reference technique is used herein is that it is hoped that you can know some of the optimization and efficiency of the components. FREFCOUNT is implemented in _addref and _release, as follows code (all code from this section taken from Delphi6, as long as your reference version is Delphi4 or more, the code is the same).

Function TinterFaceDObject._addref: integer;

Begin

Result: = interlockedIncrement (freecount);

END;

Function TinterFaceDObject._release: integer;

Begin

Result: = interlockedDecrement (freecount);

if Result = 0 THEN

DESTROY;

END;

From the code we can see that the life cycle of the interface is controlled in the two methods of _addref and _release, in fact, these two aspects are specifically used to control the life cycle of the component (about component life) Period and Interface Life Cycle We will make a few steps.), Outside them can be said to be meaningless, but reference count variables (freefcount) If it is not considering the life cycle of components, it is completely meaningless.

AddRef and release is a memory management technology called a reference count. The reference counting technology is the easiest way to make components yourself to delete components. The COM component will maintain a variable of a reference count to manage your lifecycle. When the customer gets an interface from the component, this reference count variable will increase 1 operation (_ADDREF), when the customer releases the call to the interface, the component It will automatically make a reference count reduction 1 (_RELEASE), in Delphi-based programming, we can not consider when you call these two methods, but if you get from Delphi, what you may have to consider? When these two methods are called, if you want to call these two methods yourself, this is why the author will write this section. Simply, the reference count We usually do not need to consider However, in the object reference and interface reference, you need to call these two methods, and it also involves the release of the entire release or a single release, and the release of the minimum unit is necessary to consider Quote count. For example, for a COM component, it encapsulates some COM objects, but the user may need to call several COM objects provided in the COM component through the interface, then the problem is generated, the user is likely to have a COM object. It is not fortunate to access another COM object or an interactive way. It is very unhappy that this component is a component that takes a large amount of storage, special fills to the two or more of the user. While COM objects, how do you manage components? Is the user who released this COM object after the user has completed a COM object? Or is the user released the component level after the component access is completed? Or are you more detailed to release the interfaces that you have no need for each user? This has a little impact on the efficiency of the component. At this time, we choose a different way, you may need to increase the reference count variables yourself, such as: VAR

Ofrefcount: integer; // Application of reference count of object level

Begin

.......

END;

VAR

CFREFCOUNT: INTEGER; // Component's reference count application.

Begin

......

END;

Or use the application count of the FREFCOUNT // interface level directly.

This is all we must consider. In the object model and reference model, in their hybrid applications, if you also make Delphi to automatically optimize (reference counting), then a nightmare, disaster! OK, let's discuss these possible problems or inductive as the reference count.

First we should understand that when you should call these two methods under routine, it is summarized:

2 Need to call _addref before returning to make Free FREFCOUNT. For those functions that return the pointer interface, the corresponding pointer should be performed to _ADDREF operations before returning. These functions include: queryinterface, createInstance.

2 With the interface, you should perform the _RELEASE operation on the corresponding interface, and the release operation of the interface is performed in RESLEASE.

2 Call the _addref method after assignment. The _addref should be called before the interface pointer is assigned to another interface pointer. In other words, when another reference to the interface is called, the reference count of the corresponding component or the interface pointer should be added. Object models and reference models are obvious here.

In the previous article, I am intended to make two ways of the COM object in the illustration, and this is a special example of COM components, and we can also consider the counting count. I remember that it has been mentioned before, it can be mandated to the interface, the object, as long as it is simple to give them to NIL, it can be released. The reference count as the executive official of the life cycle of management components, it needs to be trade-off in many places. As shown in the figure below: For the image above, we are analyzing reference counting techniques.

As a COM component, it can contain multiple COM objects, and the logical rules packaged by each COM object also have a size difference, such as COM objects 1 and COM object 2 packs a lot of logical rules, while COM objects 3 relative For some fewer logical rules, if User A may now need the service provided by COM objects 1 and COM objects 3, and it is necessary to access COM object 1 after this will be accessed. If this COM component only contains these two COM objects, when the user has completed the access to the COM object 1, then access to the COM object 3, then do we still make COM objects 1 in memory? Previously, we have also said that there are more logical rules in the COM object 1, and the amount of memory it occupies is relatively large. Is the COM object 3 still presented? Of course, it has not existed, but we don't know how its service is no longer available for User A. As a component, it itself maintains a set of group-level reference counts. When this component's service is completed, it will be automatically released, but the COM object does not release automatic release, then we can apply in service applications. The program is released, as before, we can observe by defining a OFRefCount. You can complete the release of COM objects, so you can reuse, making component efficiency improve, but some cases are different, if in contrast, we call the COM object 3, and then call it COM object 3. Then there is no need to release it at this time. So these are all we should think of in the programming programming and should be solved. Moreover, the situation encountered in the actual programming is far more complex. If there are multiple objects to coexist, it will be more complicated, but as long as we grasp some problems, we can solve it by reference Not as simple as simple letting us complete these reference counts, learn from themselves to observe, it is important to judge, in order to raise an anti-three, in order to raise the efficiency of the component! At the same time, as a component, it is not a user with the interface of each object, which can also be referenced by other interfaces. I will give it an instance.

Let's talk about an object model and a reference model, the application of the reference count is different from the program.

Object model and reference model, we are more familiar, such as:

VAR

PT: TCOCLASS; // Object Model.

......

VAR

PI: ICOCLASS; // Reference Model.

......

In fact, the interface model has replaced a reference model in a large extent, as two of the two codes, we can use the COM object call in the program, then use the AS operator, will take an object pointer Assignment gives or assaped in an interface pointer. At this time, it will automatically call the _addref function when applying AS in Delphi. After the interface is used, it will call the _Release function, and the user's object will be destroyed. as follows:

Procedure DosomethingwithInterface (intf: iformattednumber); Begin

ShowMessage (intf.formattedstring);

END;

PROCEDURE CREATEANDUSEROBJECT;

Begin

MyInterger: = tFormattedinteger.create (12);

DOSMETHINGWITHINTERFACE (Myinteger as iFormattedNumber);

Myinteger.SetValue (10);

END;

In this example, Myinteger is an object of a TFormattedinteger class. It is created by using an object model (that is, TFORMATTEDINTEGER.CREATE is assigned to an object variable). And in calling DOSMETHINGWITHINTEGERFACE, the AS operator is used (this is a very obvious object model, the reference, or the application of the interface model), and before, Delphi will perform _addRef when calling AS, while calling After it, it is going to do _Release operation. At this time, after the AS conversion is completed, the reference number of the IFCOUNUMBER is in fact iformattedNumber is 0, so the interface is released, so call MyintegerSetValue (10) will be wrong, and the solution is as long as we change the function declaration, as follows:

Procedure DOSMETHINGWITHINTERFACE (VAR INTF: IFORMATTEDNUMBER); or

Procedure DOSMETHINGWITHINTERFACE (Const Intf: iformattedNumber);

You can solve this problem, the reason is very simple, and the const or var type of Delphi passes the interface through the reference address instead of passing the value. By value transfer interface will cause Delphi call _addref and _Release. After correcting, you can do the following

Procedure DOSMETHINGWITHINTERFACE (VAR INTF: IFORMATTEDNUMBER);

Begin

ShowMessage (intf.formattedstring);

END;

PROCEDURE CREATEANDUSEROBJECT;

Begin

MyInterger: = tFormattedinteger.create (12);

DOSMETHINGWITHINTERFACE (Myinteger);

Myinteger.SetValue (10);

END;

The above code comes from the Internet, which is just a way to solve the composite model. In fact, at some point, let's make manual call _addref or _release is necessary.

Then, when it is still, the life cycle of the component is indeed based on FREFCOUNT, but it is not that he is in charge, the next article you will see the class, will find it the same Manage the life cycle of the component.

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

New Post(0)