What does vulkan API copy? - vulkan

When an application calls a Vulkan API command, in some cases there are pointers to memory owned by the application passed. Does Vulkan ever store such a pointer passed to it? How do you know?
For example, let's take the vkCmdWaitEvents command. I pass a pEvents pointer to an array of VkEvent. Immediately after vkCmdWaitEvents returns, can I delete that array? Or do I have to wait until that wait has been executed and the enclosing CommandBuffer has been destroyed? ie does vulkan take a copy of the array, or does it just store a pointer to the first element of the array? How do you know which?

It never does.
To quote the spec
The ownership of application-owned memory is immediately acquired by any Vulkan command it is passed into. Ownership of such memory must be released back to the application at the end of the duration of the command, so that the application can alter or free this memory as soon as all the commands that acquired it have returned.
The only time a pointer must be kept valid for more than a single call is when it is used as pUserData for a callback like the VkDebugReportCallbackCreateInfoEXT or the allocation callbacks.

Related

How Do I Manage Memory of A Decoded Object Returned From NSCoder?

I have brought back a root object from being encoded with NSCoder and have no idea how to memory manage this returned object. I have surrounded it with an autorelease pool, but the object doesn't go out with the pool. Code Here, See line 289 Line and code may change with Git Hub commits, but ultimately you will see the answer in working code, fingers crossed.
Since:
retainCount method is unpredictable, and
an autorelease pool doesn't remove the unretained object after being decoded, this article states decoded object are autoreleased and must be retained.
What is a guaranteed way to fully cause a deallocation of my decoded object?
You're managing memory returned from NSKeyedArchiver.
You either need to explicitly retain it, and call release when you are done, or use it immediately--such as write to file.
I recommend re-familiarizing yourself with the Memory Management Rules for Objective-C
Manual Memory Management is a bit tricky at first, but once you get the hang of the rules, it makes situations like this very easy to work through.
Now, if you need to ensure that the memory is removed immediately, you will need to write your own binary serializer that will follow the alloc:init pattern so the caller explicitly owns the memory. That way when you call release on the object, it will be deallocated.
NSCoder doesn't belong to that release pool.

Should I retain the argument with GCD dispatch_X (or does it retain it)

As far as I remember we had something like performSelectorOnMainThread: (and variants) do retain the objects until the method is finished executing" in Apple's documentation. So can we rely on such behavior in ios6? Cause there isn't any info in the NSObject Class Reference now. The same question in case I prefer using GCD dispatch_async/sync - if I have object created in back thread - should I choose dispatch_sync(dispatch_get_main_queue) to be sure that object won't be released until selector executes.
The thing about the Cocoa memory management system is that you NEVER have to care about this. Memory management is completely local -- you never care about what other functions do. The basic rule is -- the caller guarantees that an object argument is valid when the function is called, and does not guarantee anything else.
If a function somehow stores an object for use later, it MUST (by deduction) retain it somehow, since it does not assume that the object is valid for any longer. Conversely, as a caller of the function, you don't need to think about what a function does or whether it does something asynchronously or not, because you are not guaranteeing to the function that its argument is alive at any point after it's called.
blocks, which GCD dispatch capture their context: In this case this means they retain everything they reference until executed :)

How free memory immediately in iOS?

When you do a release, you do not immediately remove the memory. I used this code and I can see the memory before and after the use of release and it do not change. Ok, it will be release after some time.
But, what can I do for release all memory I can before start a library that will use a lot of memory? Or how can I immediately release memory?
Memory Management is a big thing in iOS but this tidbit of information helped me a lot during my development.
"Each object has a "retain count" which is increased by calling "retain" and decreased by calling "release". Once the retain count hits 0, the object is released and the memory can be used for something else.
You can "autorelease" objects. This means the retain count isn't immediately decreased, but is decreased the next time the current autorelease pool is drained.
iOS apps have an event loop in which your code runs. After each iteration of the event loop, the autorelease pool is drained. Any object with a retain count of 0 is released.
By default, autoreleased objects are returned by methods that don't begin with new, copy, mutableCopy, retain or init. This means you can use them immediately but if you don't retain them the object will be gone on the next iteration of the run loop.
If you fail to release retained objects but no longer reference them then you will have a memory leak, this can be detected by the leaks tool in Instruments.
One strategy is to autorelease everything returned by the above named methods and store objects in retain properties (or copy for strings). In your object's dealloc method, set all your properties to nil. Setting a retain/copy property to nil releases the object that it currently points to. As long as you don't have any circular references (avoided by not using retain properties for "parent" objects such as delegates), you will never encounter any leaks."
here is the link to the thread for this information
http://www.quora.com/What-is-the-best-way-to-understand-memory-management-in-iOS-development
It's a good thread with some useful code examples as well as other references.
Release frees the memory immediatly (assuming it's the last release). That means, it can be used by your application again when allocating.
Note that every applications have some chunks (pages) of free memory assigned by system and when allocating/deallocating part of a page, the released memory is not returned automatically to the system. It's just marked as free and can be used again by the application.
To understand all this, you need to learn something about how operating systems handle memory allocation, virtual memory etc.

OOP question about functions that struck me all of a sudden

May be my question is stupid. But i would like to get it cleared. We know that functions are loaded in memory only once and when you create new objects, only instance variables gets created, functions are never created. My question is, say suppose there is server and all clients access a method named createCustomer(). Say suppose all clients do something which fired createCustomer on server. So, if the method is in middle of execution and new client fires it. Will the new request be put on wait? or new request also will start executing the method? How does it all get managed when there is only one copy of function in memory? No book mentions answers to this type of questions. So i am posting here where i am bound to get answers :).
Functions are code which is then executed in a memory context. The code can be run many times in parallel (literally in parallel on a multi-processor machine), but each of those calls will execute in a different memory context (from the point of view of local variables and such). At a low level this works because the functions will reference local variables as offsets into memory on something called a "stack" which is pointed to by a processor register called the "stack pointer" (or in some interpreted languages, an analog of that register at a higher level), and the value of this register will be different for different calls to the function. So the x local variable in one call to function foo is in a different location in memory than the x local variable in another call to foo, regardless of whether those calls happen simultaneously.
Instance variables are different, they're referenced via a reference (pointer) to the memory allocated to the instance of an object. Two running copies of the same function might access the same instance variable at exactly the same time; similarly, two different functions might do so. This is why we get into "threading" or concurrency issues, synchronization, locks, race conditions, etc. But it's also one reason things can be highly efficient.
It's called "multi-threading". If each request has its own thread, and the object contains mutable data, each client will have the opportunity to modify the state of the object as they see fit. If the person who wrote the object isn't mindful of thread safety you could end up with an object that's in an inconsistent state between requests.
This is a basic threading issue, you can look it up at http://en.wikipedia.org/wiki/Thread_(computer_science).
Instead of thinking in terms of code that is executed, try to think of memory context of a thread that is changed. It does not matter where and what the actual code happens to be, and if it is the same code or a duplicate or something else.
Basically, it can happen that the function is called while it was already called earlier. The two calls are independent and may even happen to run in parallel (on a multicore machine). The way to achieve this independence is by using different stacks and virtual address spaces for each thread.
There are ways to synchronize calls, so additional callers have to wait until the first call finishes. This is also explained in the above link.

How should I memory manage objects returned by instance methods?

Plenty of Objective-C classes return objects. Statements like [[instanceOfNSWhatever objectForKey:aKey] stringValue], for instance, appear all over my (and hopefully everyone else's code).
How am I supposed to memory manage these "intermediate" objects?
Were they just created or did they always exist?
Can I retain them, and if I release the object that created them, will they be released as well?
Are they autoreleased?
What if I run [instanceOfNSWhatever stringValue] a million times in a loop? Can I dispose of all those NSStrings as needed?
I'm still learning ObjC, and while I've been good at balancing my retain counts overall, I'm definitely lacking some understanding about how these methods work. Can anyone fill me in?
You've probably already read this section of Apple's docs about memory management, but I'll point you to the section about the Object Ownership Policy just in case. You are only responsible for managing the memory of objects you "own". To quote the docs:
You own any object you create.
You "create" an object using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy).
If you own an object, you are responsible for relinquishing ownership when you have finished with it. [ie: release]
If you do not own an object, you must not release it.
The "Simple Examples" section of those docs provide good elaboration, but to put the points above in the context of your specific questions:
How am I supposed to memory manage these "intermediate" objects?
The good news is: you don't. Ignore the the memory management aspect of the "intermediate" objects in your example.
Were they just created or did they always exist?
They may have always existed, or they may have just been created. The beauty of objective-c is that you, as a consumer of those objects, don't have to care.
Can I retain them, and if I release the object that created them, will they be released as well?
You don't need to retain them if you're just passing them on to some other function, or using them as intermediate values yourself in your own calculations within the function. Say, for example, that you're returning the stringValue from your example function to someone else. There's no point in retaining it just to return it.
If you DO happen to retain it, then yes, you are responsible for issuing a corresponding release message as some point. You might, for example, retain the stringValue from your example if you want to hold on to that value as a property in your own instance. Objective-C uses reference counting. If you need that object to stick around for a long time, you must retain it so that someone else's release message doesn't cause it to vanish if the retain count falls to 0.
Are they autoreleased?
Depends. Let's say you ask for a string from instanceOfNSWhatever. If instanceOfNSWhatever has to create that string just special for you (in order to service your request), but doesn't otherwise care about that string, then yes... instanceOfNSWhatever probably put that string into the autorelease pool. If the string was already a property of instanceOfNSWhatever and it was just sending it to you in response to your request, then no, it probably wasn't autoreleased.
Again, the beauty is: you don't know and don't need to care. Since instanceOfNSWhatever created the string, it is responsible for managing it. You can ignore the memory management unless you add to the string by sending it a retain message.
What if I run [instanceOfNSWhatever stringValue] a million times in a loop? Can I dispose of all those NSStrings as needed?
No need. Again... stringValue isn't yours to manage because you didn't create it. As a technical note, if instanceOfNSWhatever really did have to create 1 million copies of stringValue to service your 1 million calls, it probably put them all in an autorelease pool, which would be drained at the end of the current cocoa event loop. Fortunately, unless you send each of those stringValue objects a retain message, you can gleefully ignore the memory management question here.
You basically manage all your memory according to the Memory Management Programming Guide for Cocoa. In short, however, you basically only need to worry about objects that you "own". You own an object if you create it (in Cocoa, you create an object by specifically allocating it using alloc or copying it using copy or one of their derivatives). If you own an object, you are responsible for releasing it when you are finished with it.
Any other object is, therefore, not owned by you. If you need to use such an object for any extended period (for example, outside the scope in which you received it), you need to specifically take ownership of the object by either sending it a retain message or copying it.
To answer your last question, if you are creating a lot of temporary objects in a loop or some other way, you can create your own autorelease pools. See the documentation for NSAutoreleasePool for more information about using them. Please note, however, that you should really only do this after you've profiled your application and found that it is using too much memory and would benefit from this kind of optimization.
Finally, if you are creating and releasing a lot of heavy objects and don't want to rely on autorelease pools, you can specifically allocate and initialize them and then make sure to release them on your own as soon as you're finished with them. Most objects that have convenience creators have similar initializers for creating the object specifically.
When working on the iPhone/iPod Touch, the autorelease objects are released when your application exits. This may be what you don't want. Especially when working with images or large chunks of data. To insure large pools of memory that are tagged autorelease get released sooner, create local autorelease pools. Like this:
NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];
-- do something that creates large autorelease memory blocks --
[localPool drain];
If you don't do this, you will find your application exiting unexpectedly.
I'll tell you a simple rules I wish I'd known when I first started Objective-C :)
If an method contains the words "alloc" or "copy" then you must [release] the object when finished.
If a method does not contain these words, you must [retain] it for it to remain valid outside of your function.
If you call [retain] you must later call [release] when finished.
This covers practically all you need to know about the basics of memory management.
ObjC makes heavy use of what are known as "auto release" pools. Objects returned from non alloc/copy functions are placed into these pools and automatically freed after your function exists.
That is why you do not need to release the results of something like [obj stringValue].