36

I'm trying to find the size of an objective-c object. I'm using something similar to:

    NSLog(@"sizeof myObject: %ld", sizeof(*myObject));

That just gives me the size of the pointer though.

What am I doing wrong?

4
  • What is the type of myObject?
    – dirkgently
    Apr 17, 2009 at 20:00
  • It's an NSDictionary in this case with arbitrary amounts of keys and values. Apr 17, 2009 at 20:04
  • Most probably because NSDictionary really is an opaque handle to a complicated data structure. Look up your headers (I don't have a Mac handy, so sorry).
    – dirkgently
    Apr 17, 2009 at 20:10
  • 2
    It's because an object is basically just a structure with a pointer to the object's class structure and that's it. The runtime actually allocates the memory for an object and lays out its internal data.
    – Jason Coco
    Apr 17, 2009 at 20:20

6 Answers 6

57

All the compiler knows about is the pointer, which is why you're getting the size of the pointer back. To see the size of the allocated object, use one of the following code snippets:

With ARC:

#import <malloc/malloc.h>

// ...

NSLog(@"Size of %@: %zd", NSStringFromClass([myObject class]), malloc_size((__bridge const void *) myObject));

Without ARC:

#import <malloc/malloc.h>

// ...

NSLog(@"size of myObject: %zd", malloc_size(myObject));

Mike Ash has a decent write-up about some of the Obj-C runtime internals on his Q&A blog: http://mikeash.com/?page=pyblog/friday-qa-2009-03-13-intro-to-the-objective-c-runtime.html

4
  • 3
    It should be noted that most classes also store their state in objects they reference via pointers. These will be allocated separately from the class (an NSString for example is a structure that contains the isa pointer, a pointer to a buffer allocated via malloc, and some other data)
    – rpetrich
    Apr 17, 2009 at 21:30
  • Yes, but in this case the size of the object's structure itself doesn't change. It's the same as any structure which has a pointer as one of its members. This would also be the case for any ivars which are objects as well.
    – Jason Coco
    Apr 17, 2009 at 21:53
  • Will this still return the correct size even in the latest runtimes where class extensions can declare instance variables (assuming that a class extension may be loaded at runtime from a bundle)?
    – dreamlax
    Jan 24, 2013 at 0:21
  • 6
    If you're using ARC, use this code instead (don't forget to import malloc.h though!): NSLog(@"Size of %@: %zd", NSStringFromClass([myObject class]), malloc_size((__bridge const void *) myObject));
    – smileyborg
    Feb 10, 2014 at 18:39
19

In the GNU Objective-C runtime, you can use (you must import <objc/objc-api.h>:

class_get_instance_size ([MyClass class]);

On Mac OS X you can use (you might need to import <objc/runtime.h>):

class_getInstanceSize ([MyClass class]);

These functions will return how much memory is required to allocate an object, it will not include memory allocated by an object when it is initialised.

1
  • 1
    Just as a note, class_getInstanceSize is only available on 10.5
    – Jason Coco
    Apr 18, 2009 at 6:02
15

First of all, i think its clear from the above posts that the object size is given by malloc_size(myObject), as suggested by Jason and also on the Mac OS reference manual:

"The malloc_size(ptr) function returns the size of the memory block that backs the allocation pointed to by ptr. The memory block size is always at least as large as the allocation it backs, and may be larger." (http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/malloc_size.3.html)

But if you are interested in finding out the size of the dictionary, keep in mind the following point:

The dictionary stores key-value pairs and does not contain the object itself in the value part but just increases a retain count of the object that was to be "added" and keeps a reference of that object with itself. Now, the dictionary itself just contains the references to the various objects (with a key attached). So if by any chance you are looking for the object size of all the objects refered to by the dictionary, technically that would not be the size of the dictionary. The size of the dictionary would be the sum of the size of all the keys plus the size of all the value-references against the keys plus the size of the parent NSObject. If you are still interested in finding out the size of the refered objects as well, try iterating over the dictionary values array:

NSArray *myArray = [myDictionary allValues];
id obj = nil;
int totalSize = 0;
for(obj in myArray)
{
    totalSize += malloc_size(obj);
}
//totalSize now contains the total object size of the refered objects in the dictionary.

Hope that answers the question.

1
  • How about the keys? Actually the NSDictionary implements its key with NSCopying protocol.
    – Itachi
    Mar 15, 2018 at 3:02
7

The size of an (objective-c) object is not easy to find because it's not even easy to define. What did you mean with "size of an objective-c object"?

The size of the reference is the size of a pointer (as returned by sizeof(obj_ref)).

The size of the memory that was allocated on creation (+alloc) may be found by the way that Jason gave in the first answer. But this depends on the runtime. The gnu-runtime differs from the apple-runtime. Eventually this is only the memory that is needed by the primitive data types the instance consists of. But not the memory that may be allocated later on (i.e. during initialization (-init)) for objects referenced by the ivars or strings.

An instance of the class

@interface FirstClass
{
    int _someInt;
    char _someChar;
}
…
@end

needs at least 5 bytes (on many systems - int size may vary) plus static overhead if the runtime needs it. The size of such an object is obvious.

But for an instance of the class

@interface SecondClass
{
    FirstClass *_someObject;
    char *_name;
    id _data;
}
…
@end

the definition of the "size" ist complicated. The object needs 12 bytes (on 32bit systems) plus overhead on allocation. But maybe the name is part of the object and allocated/freed by it. Should the memory which the actual name needs be part of the object's size? And what about the referenced objects?

1
  • 1
    Don't forget to add the 4/8 bytes to each object for the isa pointer which would be required on both runtimes.
    – Jason Coco
    Apr 18, 2009 at 2:38
5

I would suggest using class_getInstanceSize and malloc_good_size to see what it'll round up to. This will not show the ivars and whatnot inside the returned size.

#import <malloc/malloc.h>
#import <objc/runtime.h>

NSLog(@"Object Size: %zd", malloc_good_size(class_getInstanceSize([yourObject class])));
-2

I think the class description contains the size information -- it is better to look this up than querying using the sizeof operator.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.