Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

allocate specific amount of memory in swift - iOS

I am learning Instruments so I created a simple app that lets the user input a number of Mega Bytes (MB) to be allocated. And I use the "Allocations" tool in Instruments to make sure this exact amount of data is allocated. However, I always see more memory allocated in Instruments than I expect.

I did the following

func allocateMemoryOfSize(numberOfBytes: Int) {

    var bytesArray = [Int8]()
    for i in 0 ..< numberOfBytes {
        bytesArray.append(Int8(i % 7))
    }
}

I checked many questions and I found an alternative using:

func allocateMemoryOfSize(numberOfBytes: Int) {
      var imageData = UnsafeMutablePointer<Int8>.alloc(numberOfBytes)}

But I still get more memory allocated. Here is the restults in Instruments when I allocate 10 MBs:

Before running the allocateMemoryOfSize function:

Before: only 20.58 MB used

During the running of the function: 44.96 MB used During: 44.96 MB used

After the running of the function: back to only 20.58 MB After: back to only 20.58 MB

So, the function allocates around 22 MBs not 10 as wanted. What am I doing wrong? or is this extra memory management stuff?

like image 844
CSawy Avatar asked Sep 11 '15 23:09

CSawy


People also ask

How do you manage memory in Swift?

In Swift, memory management is handled by Automatic Reference Counting (ARC). Whenever you create a new instance of a class ARC allocates a chunk of memory to store information about the type of instance and values of stored properties of that instance.

What is Heap memory iOS?

1. Stack is used for static memory allocation, Heap is used for dynamic memory allocation. 2. Variables allocated on the stack are stored directly into memory and access memory very faster and its allocation dealt with compile time.

What is stack and Heap memory in Swift?

Stack is used for static memory allocation and Heap for dynamic memory allocation, both stored in the computer's RAM . For reference types, the reference is stored on the stack while the object it refers to is stored on the heap.


2 Answers

In first case when you append bytes to your array internally it uses reallocation when there is no free space. This reallocation usually doubles current array size. Here is how it looks:

enter image description here

You see that allocation was done with some additional space.

If we change you function to preallocate memory:

func allocateMemoryOfSize(numberOfBytes: Int) {
    buffer = [UInt8](count: numberOfBytes, repeatedValue: 0)
    for i in 0 ..< numberOfBytes {
        buffer[i] = UInt8(i % 7)
    }
}

We will see this:

enter image description here

Update #1

Allocation with unsafe pointer will work too. Main disadvantage is manual memory management: you have to deallocate it explicitly.

About allocation summary: when you allocate memory some system allocations also happen. In my screenshot you could see that not only 10 megabytes allocated with caller swift.slowAlloc but also 8 megabytes with caller _dispatch_alloc_try_create_heap. So you will see on graph that app uses 18 megabytes instead of 10. I don't know why this system allocation also happen because it is iOS internals. I think you need to pay attention only on your allocations. In my example I see that 10 megabytes was requested and given to app.

like image 83
John Tracid Avatar answered Nov 05 '22 21:11

John Tracid


Swift 3.1:

static var buffer = [UInt8]()

static func allocateMemoryOfSize(numberOfMegaBytes: Int) {
    print("Allocating \(numberOfMegaBytes)MB of memory")
    let mb = 1048576
    let newBuffer = [UInt8](repeating: 0, count: numberOfMegaBytes * mb)
    buffer += newBuffer
}
like image 45
Pedro Paulo Amorim Avatar answered Nov 05 '22 20:11

Pedro Paulo Amorim