Memory usage

Posted on 2004-11-05
Last Modified: 2010-04-05

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

Regards, CC.

Question by:cc042297
    LVL 17

    Expert Comment

    by:Wim ten Brink
    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...)

    Author Comment

    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!  

    Author Comment

    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 ...
    LVL 6

    Expert Comment

    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

    Author Comment

    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. ;)
    LVL 6

    Expert Comment

    memproof is a free development tool

    its main use is to test application for memory leaks
    you can google for memproof
    LVL 6

    Accepted Solution

    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.
    LVL 17

    Assisted Solution

    by:Wim ten Brink
    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;
      AnObject: TObject;
      WriteLn('Memory in use: ', AllocMemSize);
      AnObject := TObject.Create;
      WriteLn('Memory in use: ', AllocMemSize);
      Write('Press <Enter> to quit.');
      WriteLn('Memory in use: ', AllocMemSize);

    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.

    Author Comment

    Thanx Experts!

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How to run any project with ease

    Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
    - Combine task lists, docs, spreadsheets, and chat in one
    - View and edit from mobile/offline
    - Cut down on emails

    Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
    In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
    To add imagery to an HTML email signature, you have two options available to you. You can either add a logo/image by embedding it directly into the signature or hosting it externally and linking to it. The vast majority of email clients display l…
    In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor ( If you're interested in additional methods for monitoring bandwidt…

    779 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    15 Experts available now in Live!

    Get 1:1 Help Now