Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory size of classes in Objective-C

I'm interested in knowing the size of memory, allocating some Objective-C objects.

For example :

Is [NSString stringWithString:@"2"] bigger than [NSNumber numberWithInt:2] or not?

And how much bigger is [NSNumber numberWithInt:2] than int num=2 ?

Is there some documentation from Apple about this question? I think this information is very important for memory optimisation.

like image 781
Padavan Avatar asked Dec 22 '11 12:12

Padavan


Video Answer


2 Answers

Exact documentation is not available, to the best of my knowledge. NSString and (IIRC) NSNumber are implemented as class clusters, i.e. when you ask for a new object, you might actually get an object of some undocumented subclass.

It also means that things may change without warning when your program runs on a different OS version, so don't rely on exact numbers.

Now, let's try a rough estimate. Integers are 4 bytes on all current Apple platforms. Pointers are 4 bytes on iOS.

Objects are allocated on the heap; at the lowest level, heap allocation is done by malloc. I will assume that iOS's malloc implementation is derived from the one used on Mac OS - Look here for some details: http://cocoawithlove.com/2010/05/look-at-how-malloc-works-on-mac.html

The most important point is that the allocation quantum for small objects is 16 bytes, i.e. small objects will use up a multiple of 16 bytes.

Every Objective-C object contains a pointer to its class.

So, for a NSNumber containing an int I'd estimate 4 bytes for your pointer, plus 16 bytes for the object (consisting of a 4-byte class pointer and - I guess - a four-byte int, plus 8 bytes of wasted space).

For a NSString, there are different concrete subclasses for different situations. A string literal @"2" will point to a statically allocated string literal object, a string created at runtime will probably have a different representation. In general, I'd guess 4 bytes (your pointer) + 16 bytes (the NSString object) + number of characters * 2 (sizeof(unichar)) rounded up to multiples of 16.

To summarize, I estimate that NSNumbers need about five times more memory than ints. I further estimate that the same number represented as an NSString takes about 10 times more more memory than an int.

Also note that allocating objective-C objects is a lot slower than defining a local variable of type int. However, you should also remember that it will often not matter and that premature optimization is the root of all evil.

like image 96
wolfgang Avatar answered Sep 21 '22 00:09

wolfgang


There isn't such a thing as a NSString or a NSNumber, the logic of them is actually implemented in multiple different classes, each of them having more or less their own memory footprint. So its impossible to say how much a class weights before runtime (you can however ask the ObjC runtime about this). This said, another thing is that [NSNumber numberWithInt:2] will most likely return a singleton instance of NSNumber (afair every integer up to 12 is cached), so you don't really add something to your memory footprint.

And beside everything of this, going to way to optimize your memory is the wrong way! If an object weights 64 bytes more than the other, so what? 64 bytes are nothing, even on an iPhone! You will end up with bigger memory problems where you can actually optimize, eg. by lazy loading your stuff or whatever. But these problems are found during testing with Instruments and not ahead when you write your code! (You would be surprised how often a simple "optimization" made even before test running has either no effect or even has a worse performance impact!)

like image 39
JustSid Avatar answered Sep 21 '22 00:09

JustSid