欢迎来到天天文库
浏览记录
ID:37776260
大小:523.00 KB
页数:11页
时间:2019-05-30
《由TObject原码对类的内存分配》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、由TObject原码对类的内存分配一、分析TObject原码1.11.1看Delphi之祖TObject究竟干了些什么?1.1.11.1.1类的实例化 看System单元,TObject类定义实现了几个非常重要的方法。在这里我们只为了搞清楚类、实例和对象在内存中的分配情况,所以我列出这些相关的方法。如: classfunctionInitInstance(Instance:Pointer):TObject; classfunctionNewInstance:TObject;virtual; 这两个方法实
2、现了对类的实例化,其中InitInstance方法完成了在内存中开辟一段空间,并对它进行初始化用于存放一个指向vmt表的指针和零个或者多个指向接口表的指针,该接口是指它实现的接口或者他父类实现的接口。它由NewInstance负责调用,其参数为一段内存的指针。而NewInstance是当编译时由_ClassCreate负责调用,即是说在类定义后编译器就对类进行实例化了。以下这段代码表明了这一点:function_ClassCreate(AClass:TClass;Alloc:Boolean):TObject;a
3、sm{->EAX=pointertoVMT}{<-EAX=pointertoinstance}PUSHEDXPUSHECXPUSHEBXTESTDL,DLJL@@noAllocCALLDWORDPTR[EAX]+VMTOFFSETTObject.NewInstance ...... 当然类实例的释放,就由下面CleanupInstance和FreeInstance两个函数完成了,同理他们的实现原理大家也可以猜到了,这里就不多说了。1.1.21.1.2对象的初始化 由于这部分大家都明白,在TObject中
4、提供了这Create、Destroy和Free方法来完成这方面的工作。1.1.31.1.3vmt表、实例内存段和对象域关系 经过对TObject类的分析,我们可以得到如图所示的内存分布图: 其中,值得注意的是在类实例化的时候不但存放了本身实现的接口的指针,还存放了他父类所实现的接口指针。由于TObject是所有类的祖先,在整个程序运行过程中,内存对vmt表只存在一份,而对相应的类也只存在一份内实例,但是对多个对象就存在多个对象的数据域了。二.二、举例说明2.12.1Demo代码分析 在Demo实现
5、这样一段代码,我们利用这样一段代码来检查在类实例的域的大小:TTest=class(TObject) //定义一个类protected function_AddRef:Integer;stdcall; function_Release:Integer;stdcall; functionQueryInterface(constIID:TGUID;outObj):HResult;stdcall;end;I1=interface ['{0012DA37-7EDB-4F91-92DB-ED2EC7
6、44F7F4}']end;I2=interface['{640E732C-2413-4BD7-AC9C-B19AC1C384C7}']end;TTest1=class(TTest,I1) //定义对I1接口的实现类end;TTest2=class(TTest1,I2) //定义I2接口的实现类,该类继承与TTest1。end; 于是,我们利用下面的函数来得到TTest,TTest1和TTest2类的实例域的大小:procedureTForm1.Button2Click(Sender:TObject);be
7、gin ShowMessage('TTest`sInstanceSizeis'+Inttostr(TTest.InstanceSize)); ShowMessage('TTest1`sInstanceSizeis'+Inttostr(TTest1.InstanceSize)); ShowMessage('TTest2`sInstanceSizeis'+Inttostr(TTest2.InstanceSize));end; 得到的结果为: 可见他们的结果分别是4、8和12字节,为什么是如此呢?那就让我
8、们再看看上面对内存中Instance域究竟存了什么,在内存的Instance域中存放了一个指向vmt表的指针和一些指向接口的指针。由于TTest类没有实现接口,所以它的Instance域只存放了一个指向类vmt的指针大小为4字节;而TTest1实现了接口I1,所以它的Instance域中存放了一个指向它本身类vmt的指针和一个指向接口的指针,即大小为8字节;由于TTest2是继承于TT
此文档下载收益归作者所有