iOS/Obj C: Variable allocations and release - ios

I would like to print (log) what are the below variables are stored in stack and heap. I want to know where are these below variables are stored in this program. My feel is, except the first two variables , others are storing in heap.
-(void) MyFunction
{
flat value = 9.5; // Stored in Stack?
int count; // Stored in Stack?
NSString *myString = #"Incoming message"; // Stored in Heap
NSArray *myArr = [[NSArray alloc] init]; // Stored in Heap
.......
.......
}
In this case, how do i release those, using 'release'?
How can i print/log where these variables stored in stack/heap?
Does my assumption storing location(heap/stack) mentioned in above program is correct or wrong?
If an allocated objects stored in heap memory, their references will also be in heap only (or) reference will be in stack?

I would like to print (log) what are the below variables are stored in stack and heap. I want to know where are these below variables are stored in this program.
It's very unlikely that you really want to do that, but you can like this:
NSLog(#"value:%p", &value);
NSLog(#"count:%p", &count);
NSLog(#"myString:%p", myString);
NSLog(#"myArr:%p", myArr);
Regarding where they're stored:
float value = 9.5; // Stored in Stack?
Probably, if you actually modify it. It might also be stored in a register. Or it might be completely optimized away if it turns out to be constant. The above log statements will force it to be stored on the stack (so it can have an address), so asking where the variable is stored can actually change where it is stored.
But yes, as a back-of-the-envelope approximation of unoptimized code, automatic variables are stored on the stack.
int count; // Stored in Stack?
Again, probably. Of course if you never access it, it could be completely optimized away.
NSString *myString = #"Incoming message"; // Stored in Heap
The constant string that this points to is stored in the text segment (in the code itself). The myString pointer itself is an automatic variable, however, and that is stored on the stack as above.
NSArray *myArr = [[NSArray alloc] init]; // Stored in Heap
This could be optimized down to a constant empty array stored in the framework. Or it could be on the heap.
In this case, how do i release those, using 'release'?
No. You manage these using ARC, which will manage retains and releases for you. You should not manually call release in most code.
If an allocated objects stored in heap memory, their references will also be in heap only (or) reference will be in stack?
The pointer variable itself is stored on the stack.

You can log the values of pointer variables with the %p format specifier, e.g.: NSLog(#"%p", myString);
However that in itself won't tell you whether a given address is in a particular memory segment (though you can generally make some educated guesses based on address ranges -- for example, stack addresses begin at the end of a program's address space, so their values tend be much larger than heap addresses; distinguishing heap addresses from static addresses can be a little tricker though).
You're correct in thinking that value and count will be store on the stack, but the object myString refers to will be stored in static memory rather than in heap. However, myArr will be allocated in heap.
Automatic variables (method and function arguments, and local variables not explicitly declared static) are allocated on the stack, regardless of the values you initialize them with.

Related

where is NSString literal placed in memory?

I made a test for NSString.
int a = 10;
NSString *str1 = #"str";
NSString *str2 = [NSString stringWithFormat:#"str"];
NSString *str3 = #"str";
NSString *str4 = #"str2";
NSLog(#"%p %p | 3 %p | 4 %p | a %p", str1,str2,str3,str4,&a);
result is
0x1286287c8 0xa000000007274733 | 3 0x1286287c8 | 4 0x1286287e8 | a 0x7ffeeb215b14
this test placed in iPhone 6s(11.1) Simulator. So what's the place of str1 in memory? is it Stack or Heap?
Note that your curious value, 0xa000000007274733, is odd - that is the least significant bit is set. Object pointers are usually even - see the other ones you've displayed.
An odd-valued pointer is an indicator that it might be one of Apple's tagged pointers, where instead of allocating an object the data is stored directly in the pointer itself.
The Unicode for r is 0x72, s & t follow. So it looks like you have the Unicode for the characters in there.
Mike Ash did a good article on tagged strings back in 2015, though your value doesn't seem to match the scheme he discovered. However I'd go with this being a tagged pointer of some kind.
HTH
Addendum
I see you edited the question to ask whether the literal is in the stack or heap, and that made be realise you were asking about str1, oops. The literal will be in a "data segment", in the same area of memory as the code.
To see this try allocating a general object (an NSObject will do, but not an NSString which tend to get special treatment) to see where a heap object goes, and taking the address of a C function to see where the code goes. You'll probably find str1 is closest to the latter.
So what's the place of str1 in memory? is it Stack or Heap?
A string -- an Objective-C object -- can never be on the stack *. Stack based ObjC objects have never been supported.
An Objective-C object can be in one of three places, though. Well, two, really, and the third is weird.
An object can be on the heap. It is, effectively, in a hunk of memory that was malloc()d (though not always malloc(), but that is an implementation detail) and the first 4 (32 bit) or 8 (64 bit) bytes will be a pointer to the class of the object and, possibly, some metadata encoded into said pointer (i.e. don't just grab the isa and think you've got a valid class).
An object may be in the readonly memory that is mapped into memory by dyld. These objects are actually created by the linker and are a part of the executable. NSString constants fall into this category. NSArray and NSDictionary constants do not; they are still dynamically allocated as per (1) above. Note one oddity; because they are not allocated, they do not follow the string 16 byte (typically) aligned allocation patterns of (1). In fact, they may be 2 byte aligned (they won't likely be odd, but that's another implementation detail that may change).
They may be a tagged pointer. If the lowest order bit is set-- an odd address-- that means "tagged pointer". But that, too, is an implementation detail that can-- and has-- changed. With a tagged pointer, there is no allocation at all. The "pointer" isn't a pointer at all. The pointer is the data; for an NSNumber, the value and type of the contained number is encoded in the object "pointer".
The one exception is a Block. They can be in the heap, in the memory mapped data segment loaded by the executable, or on the stack.
However, that's another implementation detail. Only, in this case, you are exposed to it. While the compiler, under ARC, actually makes it largely fully automatic at this time, there are still a couple of cases where you need to copy a block to ensure it moves to the heap before the declarative scope disappears.
However, since the class of a Block isn't exposed nor is there any means of manually allocating Blocks, I'm going to stick with Objective-C objects never being on the stack. ;)

Delphi dynamic array efficiency

I am not a Delphi expert and I was reading online about dynamic arrays and static arrays. In this article I have found a chapter called "Dynamic v. Static Arrays" with a code snippet and below the author says:
[...] access to a dynamic array can be faster than a static array!
I have understood that dynamic arrays are located on the heap (they are implemented with references/pointers).
So far I know that the access time is better on dynamic arrays. But is that the same thing with the allocation? Like if I called SetLength(MyDynArray, 5) is that slower than creating a MyArray = array[0..4] of XXX?
So far I know that the access time is better on dynamic arrays.
That is not correct. The statement in that article is simply false.
But is that the same thing with the allocation? Like if I called SetLength(MyDynArray, 5) is that slower than creating a MyArray = array[0..4] of XXX?
A common fallacy is that static arrays are allocated on the heap. They could be global variables, and so allocated automatically when the module is loaded. They could be local variables and allocated on the stack. They could be dynamically allocated with calls to New or GetMem. Or they could be contained in a compound type (e.g. a record or a class) and so allocated in whatever way the owning object is allocated.
Having got that clear, let's consider a couple of common cases.
Local variable, static array type
As mentioned, static arrays declared as local variables are allocated on the stack. Allocation is automatic and essentially free. Think of the allocation as being performed by the compiler (when it generates code to reserve a stack frame). As such there is no runtime cost to the allocation. There may be a runtime cost to access because this might generate a page fault. That's all perfectly normal though, and if you want to use a small fixed size array as a local variable then there is no faster way to do it.
Member variable of a class, static array type
Again, as described above, the allocation is performed by the containing object. The static array is part of the space reserved for the object and when the object is instantiated sufficient memory is allocated on the heap. The cost for heap allocation does not typically depend significantly on the size of the block to be allocated. An exception to that statement might be really huge blocks but I'm assuming your array is relatively small in size, tens or hundreds of bytes. Armed with that knowledge we can see again that the cost for allocation is essentially zero, given that we are already allocating the memory for the containing object.
Local variable, dynamic array type
A dynamic array is represented by a pointer. So your local variable is a pointer allocated on the stack. The same argument applies as for any other local variable, for instance the local variable of static array type discussed above. The allocation is essentially free. Before you can do anything with this variable though, you need to allocate it with a call to SetLength. That incurs a heap allocation which is expensive. Likewise when you are done you have to deallocate.
Member variable of a class, dynamic array type
Again, allocation of the dynamic array pointer is free, but you must call SetLength to allocate. That's a heap allocation. There needs to be a deallocation too when the object is destroyed.
Conclusion
For small arrays, whose lengths are known at compile time, use of static arrays results in more efficient allocation and deallocation.
Note that I am only considering allocation here. If allocation is a relatively insignificant portion of the time spent working with the object then this performance characteristic may not matter. For instance, suppose the array is allocated at program startup, and then used repeatedly for the duration of the program. In such a scenario the access times dominate the allocation times and the difference between allocation times becomes insignificant.
On the flip side, imagine a short function called repeatedly during the programs lifetime, let's suppose this function is the performance bottleneck. If it operates on a small array, then it is possible that the allocation cost of using a dynamic array could be significant.
Very seldom can you draw hard and fast rules with performance. You need to understand how the tools work, and understand how your program uses these tools. You can then form opinions on which coding strategies might perform best, opinions that you should then test by profiling. You will be surprised more often than you might expect that your intuition is not a good predictor of performance.

iOS: memory footprint of local variable defined in methods

I need to have a few hard coded collection data (ie NSArray, NSDictionary), and I'm wondering what the memory footprint is it like, for example,
- (NSArray *)getDataA
{
NSArray *data = #[ #{#"key": #"value"} ];
return data;
}
And the actual data is way more than the key-value in the above code.
I guess the local variables are stored on stack and the actual value are in heap, but before calling getDataA, do they occupy any memory space?
Thanks!
Keep in mind that a structure such as in the question is created by code executing at runtime, they will not be static. Constant NSStrings are the exception and possibly a few other special cases like some NSNumbers.
Unless you have MBs the size is not really important. Like all optimizations: don't. Do the most clear implementation and then measure.

Go memory layout compared to C++/C

In Go, it seems there are no constructors, but it is suggested that you allocate an object of a struct type using a function, usually named by "New" + TypeName, for example
func NewRect(x,y, width, height float) *Rect {
return &Rect(x,y,width, height)
}
However, I am not sure about the memory layout of Go. In C/C++, this kind of code means you return a pointer, which point to a temporary object because the variable is allocated on the stack, and the variable may be some trash after the function return. In Go, do I have to worry such kind of thing? Because It seems no standard shows that what kind of data will be allocated on the stack vs what kind of data will be allocated on the heap.
As in Java, there seems to have a specific point out that the basic type such as int, float will be allocated on the stack, other object derived from the object will be allocated on the heap. In Go, is there a specific talk about this?
The Composite Literal section mentions:
Taking the address of a composite literal (§Address operators) generates a unique pointer to an instance of the literal's value.
That means the pointer returned by the New function will be a valid one (allocated on the stack).
Calls:
In a function call, the function value and arguments are evaluated in the usual order.
After they are evaluated, the parameters of the call are passed by value to the function and the called function begins execution.
The return parameters of the function are passed by value back to the calling function when the function returns.
You can see more in this answer and this thread.
As mentioned in "Stack vs heap allocation of structs in Go, and how they relate to garbage collection":
It's worth noting that the words "stack" and "heap" do not appear anywhere in the language spec.
The blog post "Escape Analysis in Go" details what happens, mentioning the FAQ:
When possible, the Go compilers will allocate variables that are local to a function in that function's stack frame.
However, if the compiler cannot prove that the variable is not referenced after the function returns, then the compiler must allocate the variable on the garbage-collected heap to avoid dangling pointer errors.
Also, if a local variable is very large, it might make more sense to store it on the heap rather than the stack.
The blog post adds:
The code that does the “escape analysis” lives in src/cmd/gc/esc.c.
Conceptually, it tries to determine if a local variable escapes the current scope; the only two cases where this happens are when a variable’s address is returned, and when its address is assigned to a variable in an outer scope.
If a variable escapes, it has to be allocated on the heap; otherwise, it’s safe to put it on the stack.
Interestingly, this applies to new(T) allocations as well.
If they don’t escape, they’ll end up being allocated on the stack. Here’s an example to clarify matters:
var intPointerGlobal *int = nil
func Foo() *int {
anInt0 := 0
anInt1 := new(int)
anInt2 := 42
intPointerGlobal = &anInt2
anInt3 := 5
return &anInt3
}
Above, anInt0 and anInt1 do not escape, so they are allocated on the stack;
anInt2 and anInt3 escape, and are allocated on the heap.
See also "Five things that make Go fast":
Unlike C, which forces you to choose if a value will be stored on the heap, via malloc, or on the stack, by declaring it inside the scope of the function, Go implements an optimisation called escape analysis.
Go’s optimisations are always enabled by default.
You can see the compiler’s escape analysis and inlining decisions with the -gcflags=-m switch.
Because escape analysis is performed at compile time, not run time, stack allocation will always be faster than heap allocation, no matter how efficient your garbage collector is.

Why does object have a pointer and not an int?

If we type
MyObject *obj = [[MyObject alloc] init];
"obj" is a pointer to the memory address.
...When we create an int, we type:
int x = 10;
Why don't we type?
int *x = 10;
The question is, why do we need a pointer to object and not int, float, etc...
Efficiency.
Moving an int from one place to another is easy. Moving an object needs a little bit more work from the CPU. Moving the address of an object is as easy as moving an int.
In plain C, it is common to handle pointers to structs for the same reason. C makes it easy with the -> operator.
There are languages where you can create objects “without a pointer”, on the stack. C++, for example. One great thing about having objects on the stack is that they get automatically deallocated when the scope ends, which helps with memory management. It’s also faster.
One bad thing about having objects on the stack is that they get automatically deallocated when the scope ends and the stack disappears. And since objects are usually longer-lived than local variables, you would have to copy the object’s memory somewhere. It’s entirely possible, but it complicates matters.
And it’s not just the memory lifecycle that’s complicated with stack-based objects. Consider assignment, foo = bar for two object types. If the objects are always pointers (Class*), you just assigned a pointer and got two pointers to the same objects; easy. If foo is stack-based (Class), the assignment semantics starts to get blurry – you could well end with a copy of the original object.
Introducing a rule that all objects are allocated on the heap (“with pointers”) is a great simplification. And as it happens, the speed difference doesn’t matter that much, and the compiler can now also automatically insert code to deallocate heap-based objects after they go out of scope, so it’s generally a win-win situation.
You can have pointer for int, float as well.
Objects are created on heap. To access it, you need the address. Thats why they are of pointer types.
Because that is the nature of an object.
Objective-C is directly derrived from C. That is why objects are referred to as pointers. An int-type variable of the size of an memory address is a pointer.
In the end, an object in memory is not much different from an struct in memory.
However, when working in Objective-C it is advisable to think of these variables as references of objects rather than pointers to an object's memory areas. Think of them like Java does and do not spend much thoughts on how the system manages the references. There are far more important things to think of such as alloc/retain vs. release/autorelease or following the much easier ARC rules respectively.
BTW:
MyObject obj;
That would declare an object, not a pointer. It is not possible in Objective-C (afaik) and certainly not reasonable. But if it was reasonable and possible, that is what the syntax would look like.
int *x;
That does create a pointer to an int. For using it you would have to allocate memory and assign its address to x. Rarerly reasonable in Objective C either but quite useful in standard C.
its the difference between objects being on the stack or the heap.
going int x = 10 x is now on the stack. int *x = 10 is just simply wrong (well most likely not what you want) since that is declaring a pointer to address 10 whatever that may be. you would want int *x = malloc(sizeOf(int)); as CodaFi suggested. that will allocate memory on the heap of the size of an int.
going MyObject *obj = [[Myobject alloc] init]; the compiler behind the scenes is allocating your object to the heap for you, but its basically the same principle

Resources