Memory usage

Hi,

Does anyone know for sure how much more memory a TObject instance allocates then if it is declared as simple record?

Regards, CC.

cc042297Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Wim ten BrinkSelf-employed developerCommented:
About 100 to 200 bytes more, depending on the Delphi version. Every object has some additional overhead pointing to the related virtual method table and for some additional internal data. An exact value isn't easy to provide since there's a dependency on the exact class type. Objects are more expensive in memory usage so if you need to save memory, don't use them. (Or buy more RAM, which is what I always advise my customers...)
0
cc042297Author Commented:
Hi Alex!

Just to make sure I got it wright: EVERY instance of a TObject uses 100 to 200 bytes? .... that is much more than I expected!  
0
cc042297Author Commented:
I have tried to make a rough estimation with the help of Win XP's taskmanager. I created 1.000.000 instance of a record, and the same amount of an object. They both had only 2 integer fields. If taskmanager is correct the average difference is around 4 bytes per instance ...
0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

vadim_tiCommented:
I do not think you will have a big overhead, because overhead will be on class level and not on instance level

you can see it with memproof

declare class and begin create instances of this class and do not free them.
you will see there are no overhead
0
cc042297Author Commented:
I have taken a look at TObject's declaration and some of the methods and class methods and from there I had the same impression. I just did not know if the compiler adds anything else.

 "you can see it with memproof" - Is 'memproof' a program?  Never heard of. ;)
0
vadim_tiCommented:
memproof is a free development tool

its main use is to test application for memory leaks
you can google for memproof
0
gwalkeriqCommented:
Objects are not much different in size than the equivalent record, the only difference being enough RTTI for to identify the object type (a single pointer type IIRC). There is no object data in the TObject class, but the virtual methods and RTTI fnctions require a simple simple and fast method to do track thinks on a per-object basis, which is fortunately the VMS in both bases.

It is nearly impossible to confirm this however, since the Delphi compiler itself is closed source. However, if you call the InstanceSize method on an object that has not other data you will see that the size if 4 bytes., and if you look at TObject.InitInstance() in the system uint you come real close to confirming this -- unless you assume Borland goes to devious extremes to hide the implmentation

There is a 1-time charge for the vtable needed for each different class, this is roughly 100 bytes (92 with D6, see the Virtual Table Method Entries in the system unit).

However, there is a potentially huge difference in the Objects are allways allocated from the heap. Each time you create an object using the generic heap allocation. The amount of wasted slack and memory fragmentation this produced complicates the memory use issue considerably. At a minimum, most generic allocators add an extra negative offset header that  lets the deallocator know how big the memory block is -- have not disassembled Borland manager, but it could use the value from the VTBL instead a using the underlying generic memory allocator. However, there is a bigger problem in that generic allocators do not allow random allocate / free patterns without introducing extra memory (and cpu) overhead because of this. I've read before that the Delphi heap manager only managers a since heap, so in a program with lots of objects of different sizes you are liable to get lots of fragmentation and slack (both of which are bad)

If you are allocating 1 million objects, it's probably a real good idea to use a private memory allocator (see the NewInstance / FreeInstance methods of TObject). Though I've not done this with Delphi, I've used private class allocators in C++ programs with millions of objects and have seen significant memory & performance gains.

My take on this would be, its 4 bytes (or more), but if you are willing to write the private allocator, you can essentially guarantee that you only have 4 additional bytes of overhead.

An easier approach is to get a better memory allocator than the one Borland uses, I seem to recall that there is one, but it may be defunct since I can't find it with a couple of obvious Googles.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Wim ten BrinkSelf-employed developerCommented:
A TObject is actually just a pointer to a memory location, thus 4 bytes. If the object is created, the object points to some allocated piece of memory containing the data. However, Delphi also maintains some additional type information at that location. A pointer to the VMT table of the object and I think another pointer to the Interface table. (for support of interfaces) These tables do require a small amount of memory for every classtype, not for every object.

But the best way to get this info is by using this project with Delphi 7:

program Project7;
{$APPTYPE CONSOLE}
var
  AnObject: TObject;
begin
  WriteLn('Memory in use: ', AllocMemSize);
  AnObject := TObject.Create;
  WriteLn('Memory in use: ', AllocMemSize);
  AnObject.Free;
  Write('Press <Enter> to quit.');
  WriteLn('Memory in use: ', AllocMemSize);
  ReadLn;
end.

AllocMemSize tells how much the Delphi memory manager has allocated in memory. Before the object is created, it is 0. When created, it went up to 8 and thus suggesting it has stored two pointers. After freeing, it is back to 0. Since TObject doesn't contain any data, it must be something that provides type information for the objects. Records just don't have any type information.
That TObject contains a pointer for a reference to an interface table became clear to me when I used "AnObject := TInterfacedObject.Create;" to create an interfaced object. TInterfacedObject contains one data element, a reference counter, and indeed the memory usage went up to 12 bytes. Exactly the size of the reference counter. But it must support the interface usage thus TObject itself supports interfaces from the basics.

In older Delphi versions the amount of memory usage might be a lot lower. I'm not 100% sure but I believe that with the older Delphi versions, every object had it's own VMT allocated with the object allocation itself. I just can't test it anymore...

Thus, the size of objects is:
4 bytes per object for a pointer to the Virtual Memory table.
4 bytes per object for a pointer to the Interface table.
About 100 bytes per class for the Virtual Memory table.
An unknown amount per class for the Interface table.
And if you have a pointer pointing at the object, an additional 4 bytes for the pointer.
Plus the size of the data elements in the object.

The size for a record is just the size of the data elements and not a byte more. Unless you have a pointer to a record in which case you have an additional 4 bytes for the pointer.

With records, pointers are optional to get access to the data. If the record is declared as global or local variable then Delphi knows the exact location of the data thus doesn't need the address. But with objects, you always get a pointer pointing to some other address.
0
cc042297Author Commented:
Thanx Experts!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.