Sunday, March 26, 2023
Learning Code
  • Home
  • JavaScript
  • Java
  • Python
  • Swift
  • C++
  • C#
No Result
View All Result
  • Home
  • JavaScript
  • Java
  • Python
  • Swift
  • C++
  • C#
No Result
View All Result
Learning Code
No Result
View All Result
Home Swift

Memory layout in Swift – The.Swift.Dev.

learningcode_x1mckf by learningcode_x1mckf
September 16, 2022
in Swift
0
Memory layout in Swift – The.Swift.Dev.
74
SHARES
1.2k
VIEWS
Share on FacebookShare on Twitter


Reminiscence structure of worth varieties in Swift


Reminiscence is only a bunch of `1`s and `0`s, merely known as bits (binary digits). If we group the stream of bits into teams of 8, we will name this new unit byte (eight bit is a byte, e.g. binary 10010110 is hex 96). We will additionally visualize these bytes in a hexadecimal kind (e.g. 96 A6 6D 74 B2 4C 4A 15 and so on). Now if we put these hexa representations into teams of 8, we’ll get a brand new unit known as word.

This 64bit reminiscence (a phrase represents 64bit) structure is the fundamental basis of our fashionable x64 CPU structure. Every phrase is related to a digital reminiscence tackle which can be represented by a (usually 64bit) hexadecimal quantity. Earlier than the x86-64 period the x32 ABI used 32bit lengthy addresses, with a most reminiscence limitation of 4GiB. Luckily we use x64 these days. 💪


So how can we retailer our information varieties on this virtual memory tackle area? Properly, lengthy story brief, we allocate simply the correct amount of area for every information kind and write the hex illustration of our values into the reminiscence. It is magic, offered by the working system and it simply works.


We may additionally begin speaking about memory segmentation, paging, and different low degree stuff, however truthfully talking I actually do not know the way these issues work simply but. As I am digging deeper and deeper into low level stuff like this I am studying so much about how computer systems work underneath the hood.


One vital factor is that I already know and I wish to share with you. It’s all about memory access on varied architectures. For instance if a CPU’s bus width is 32bit meaning the CPU can solely learn 32bit phrases from the reminiscence underneath 1 learn cycle. Now if we merely write each object to the reminiscence with out correct information separation that may trigger some bother.


┌──────────────────────────┬──────┬───────────────────────────┐
│           ...            │  4b  │            ...            │
├──────────────────────────┴───┬──┴───────────────────────────┤
│            32 bytes          │            32 bytes          │
└──────────────────────────────┴──────────────────────────────┘


As you may see if our reminiscence information is misaligned, the primary 32bit learn cycle can solely learn the very first a part of our 4bit information object. It’s going to take 2 learn cycles to get again our information from the given reminiscence area. That is very inefficient and in addition harmful, that is why a lot of the programs will not enable you unaligned entry and this system will merely crash. So how does our memory layout appears to be like like in Swift? Let’s take a fast take a look at our information varieties utilizing the built-in MemoryLayout enum kind.


print(MemoryLayout<Bool>.dimension)      
print(MemoryLayout<Bool>.stride)    
print(MemoryLayout<Bool>.alignment) 


print(MemoryLayout<Int>.dimension)       
print(MemoryLayout<Int>.stride)     
print(MemoryLayout<Int>.alignment)  


As you may see Swift shops a Bool worth utilizing 1 byte and (on 64bit programs) Int can be saved utilizing 8 bytes. So, what the heck is the distinction between size, stride and alignment?

The alignment will inform you how a lot reminiscence is required (a number of of the alignment worth) to save lots of issues completely aligned on a reminiscence buffer. Dimension is the variety of bytes required to really retailer that kind. Stride will inform you in regards to the distance between two parts on the buffer. Don’t fret in the event you do not perceive a phrase about these casual definitions, it’s going to all make sense simply in a second.


struct Instance 
    let foo: Int  
    let bar: Bool 


print(MemoryLayout<Instance>.dimension)      
print(MemoryLayout<Instance>.stride)    
print(MemoryLayout<Instance>.alignment) 

When setting up new information varieties, a struct in our case (courses work totally different), we will calculate the reminiscence structure properties, based mostly on the reminiscence structure attributes of the collaborating variables.


┌─────────────────────────────────────┬─────────────────────────────────────┐
│         16 bytes stride (8x2)       │         16 bytes stride (8x2)       │
├──────────────────┬──────┬───────────┼──────────────────┬──────┬───────────┤
│       8 bytes    │  1b  │  7 bytes  │      8 bytes     │  1b  │  7 bytes  │
├──────────────────┴──────┼───────────┼──────────────────┴──────┼───────────┤
│   9 bytes dimension (8+1)    │  padding  │   9 bytes dimension (8+1)    │  padding  │
└─────────────────────────┴───────────┴─────────────────────────┴───────────┘


In Swift, easy varieties have the identical alignment worth dimension as their dimension. In case you retailer normal Swift information varieties on a contiguous reminiscence buffer there is no padding wanted, so each stride can be equal with the alignment for these varieties.

When working with compound varieties, such because the Instance struct is, the memory alignment worth for that kind can be chosen utilizing the utmost worth (8) of the properties alignments. Dimension would be the sum of the properties (8 + 1) and stride may be calculated by rounding up the scale to the following the following a number of of the alignment. Is that this true in each case? Properly, not precisely…


struct Instance 
    let bar: Bool 
    let foo: Int  


print(MemoryLayout<Instance>.dimension)      
print(MemoryLayout<Instance>.stride)    
print(MemoryLayout<Instance>.alignment) 


What the heck occurred right here? Why did the scale improve? Dimension is hard, as a result of if the padding is available in between the saved variables, then it’s going to improve the general dimension of our kind. You may’t begin with 1 byte then put 8 extra bytes subsequent to it, since you’d misalign the integer kind, so that you want 1 byte, then 7 bytes of padding and eventually the 8 bypes to retailer the integer worth.


┌─────────────────────────────────────┬─────────────────────────────────────┐
│        16 bytes stride (8x2)        │        16 bytes stride (8x2)        │
├──────────────────┬───────────┬──────┼──────────────────┬───────────┬──────┤
│     8 bytes      │  7 bytes  │  1b  │     8 bytes      │  7 bytes  │  1b  │
└──────────────────┼───────────┼──────┴──────────────────┼───────────┼──────┘
                   │  padding  │                         │  padding  │       
┌──────────────────┴───────────┴──────┬──────────────────┴───────────┴──────┐
│       16 bytes dimension (1+7+8)         │       16 bytes dimension (1+7+8)         │
└─────────────────────────────────────┴─────────────────────────────────────┘


That is the principle purpose why the second instance struct has a barely elevated dimension worth. Be at liberty to create different varieties and follow by drawing the reminiscence structure for them, you may at all times test in the event you had been right or not by printing the reminiscence structure at runtime utilizing Swift. 💡


This complete drawback is actual properly defined on the [swift unboxed] weblog. I’d additionally prefer to advocate this article by Steven Curtis and there’s another nice submit about Unsafe Swift: A road to memory. These writings helped me so much to grasp reminiscence structure in Swift. 🙏


Reference varieties and reminiscence structure in Swift

You might also like

Introducing – AI Utils for macOS

Encoding and decoding data using the Hummingbird framework

Hummingbird routing and requests – The.Swift.Dev.

I discussed earlier that courses behave fairly totally different that is as a result of they’re reference varieties. Let me change the Instance kind to a category and see what occurs with the reminiscence structure.


class Instance 
    let bar: Bool = true 
    let foo: Int = 0 


print(MemoryLayout<Instance>.dimension)      
print(MemoryLayout<Instance>.stride)    
print(MemoryLayout<Instance>.alignment) 


What, why? We had been speaking about reminiscence reserved within the stack, till now. The stack reminiscence is reserved for static reminiscence allocation and there is an different factor known as heap for dynamic reminiscence allocation. We may merely say, that worth varieties (struct, Int, Bool, Float, and so on.) dwell within the stack and reference varieties (courses) are allotted within the heap, which isn’t 100% true. Swift is sensible sufficient to carry out further reminiscence optimizations, however for the sake of “simplicity” let’s simply cease right here.


You may ask the query: why is there a stack and a heap? The reply is that they’re fairly totally different. The stack may be sooner, as a result of reminiscence allocation occurs utilizing push / pop operations, however you may solely add or take away gadgets to / from it. The stack dimension can be restricted, have you ever ever seen a stack overflow error? The heap permits random reminiscence allocations and it’s a must to just remember to additionally deallocate what you’ve got reserved. The opposite draw back is that the allocation course of has some overhead, however there isn’t any dimension limitation, besides the bodily quantity of RAM. The stack and the heap is kind of totally different, however they’re each extraordinarily helpful reminiscence storages. 👍


Again to the subject, how did we get 8 for each worth (dimension, stride, alignment) right here? We will calculate the true size (in bytes) of an object on the heap through the use of the class_getInstanceSize methodology. A category at all times has a 16 bytes of metadata (simply print the scale of an empty class utilizing the get occasion dimension methodology) plus the calculated dimension for the occasion variables.


class Empty 
print(class_getInstanceSize(Empty.self)) 

class Instance 
    let bar: Bool = true 
    let foo: Int = 0     

print(class_getInstanceSize(Instance.self)) 


The reminiscence structure of a category is at all times 8 byte, however the precise dimension that it will take from the heap depends upon the occasion variable varieties. The opposite 16 byte comes from the “is a” pointer and the reference depend. If you understand in regards to the Goal-C runtime a bit then this could sound acquainted, but when not, then don’t be concerned an excessive amount of about ISA pointers for now. We’ll discuss them subsequent time. 😅


Swift makes use of Automatic Reference Counting (ARC) to trace and handle your app’s reminiscence utilization. In a lot of the circumstances you do not have to fret about guide reminiscence administration, because of ARC. You simply should just remember to do not create robust reference cycles between class situations. Luckily these circumstances may be resolved simply with weak or unowned references. 🔄


class Writer 
    let identify: String

    
    weak var submit: Submit?

    init(identify: String)  self.identify = identify 
    deinit  print("Writer deinit") 


class Submit 
    let title: String
    
    
    var writer: Writer?

    init(title: String)  self.title = title 
    deinit  print("Submit deinit") 



var writer: Writer? = Writer(identify: "John Doe")
var submit: Submit? = Submit(title: "Lorem ipsum dolor sit amet")

submit?.writer = writer
writer?.submit = submit

submit = nil
writer = nil



As you may see within the instance above if we do not use a weak reference then objects will reference one another strongly, this creates a reference cycle they usually will not be deallocated (deinit will not be known as in any respect) even in the event you set particular person tips that could nil. This can be a very fundamental instance, however the true query is when do I’ve to make use of weak, unowned or robust? 🤔


I do not prefer to say “it relies upon”, so as an alternative, I might prefer to level you into the best path. In case you take a better take a look at the official documentation about Closures, you will see what captures values:

  • World capabilities are closures which have a reputation and don’t seize any values.
  • Nested capabilities are closures which have a reputation and might seize values from their enclosing perform.
  • Closure expressions are unnamed closures written in a light-weight syntax that may seize values from their surrounding context.

As you may see global (static functions) don’t increment reference counters. Nested capabilities alternatively will seize values, similar factor applies to closure expressions and unnamed closures, however it is a bit extra difficult. I might prefer to advocate the next two articles to grasp extra about closures and capturing values:

Lengthy story brief, retain cycles suck, however in a lot of the circumstances you may keep away from them simply through the use of simply the best key phrase. Beneath the hood, ARC does an ideal job, besides a couple of edge circumstances when it’s a must to break the cycle. Swift is a memory-safe programming language by design. The language ensures that each object can be initialized earlier than you would use them, and objects residing within the reminiscence that are not referenced anymore can be deallocated mechanically. Array indices are additionally checked for out-of-bounds errors. This provides us an additional layer of security, besides in the event you write unsafe Swift code… 🤓


Anyway, in a nutshell, that is how the reminiscence structure appears to be like like within the Swift programming language.




Source link

Share30Tweet19
learningcode_x1mckf

learningcode_x1mckf

Recommended For You

Introducing – AI Utils for macOS

by learningcode_x1mckf
March 24, 2023
0
Introducing – AI Utils for macOS

⚠️ REQUIRES a FREE OpenAI API key. You will get one utilizing this hyperlink. ⚠️ Improve your productiveness with our AI powered utility application. - accessible...

Read more

Encoding and decoding data using the Hummingbird framework

by learningcode_x1mckf
March 22, 2023
0
Encoding and decoding data using the Hummingbird framework

HTTP is all about sending and receiving information over the community. Initially it was solely utilized to switch HTML paperwork, however these days we use HTTP to switch...

Read more

Hummingbird routing and requests – The.Swift.Dev.

by learningcode_x1mckf
March 17, 2023
0
Hummingbird routing and requests – The.Swift.Dev.

Routing on the server facet means the server goes to ship a response primarily based on the URL path that the consumer referred to as when firing up...

Read more

Building a Scrollable Custom Tab Bar in SwiftUI

by learningcode_x1mckf
March 10, 2023
0
Building a Scrollable Custom Tab Bar in SwiftUI

Whether or not you’re making a social media app or a productiveness device, the tab bar interface can improve the consumer expertise by making it extra intuitive and...

Read more

Beginner’s guide to server-side Swift using the Hummingbird framework

by learningcode_x1mckf
March 8, 2023
0
Beginner’s guide to server-side Swift using the Hummingbird framework

Swift on the Server in 2023 Three years in the past I began to focus on Vapor, the preferred web-framework written in Swift, which served me very...

Read more
Next Post
How to Convert HTML to an Image in JavaScript

How to Convert HTML to an Image in JavaScript

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Related News

Google expands open source bounties, will soon support Javascript fuzzing too – ZDNet

TIOBE: C++ overtakes Java in programming language popularity – Developer News

February 18, 2023
Google expands open source bounties, will soon support Javascript fuzzing too – ZDNet

Rust is kind to its coders, C++ makes you feel terrible – eFinancialCareers (US)

February 20, 2023
Quick Tip: How to Use the Spread Operator in JavaScript

Quick Tip: How to Use the Spread Operator in JavaScript

October 5, 2022

Browse by Category

  • C#
  • C++
  • Java
  • JavaScript
  • Python
  • Swift

RECENT POSTS

  • 2023 Java roadmap for developers – TheServerSide.com
  • YS Jagan launches Ragi Java in Jagananna Gorumudda, says focused on intellectual development of students – The Hans India
  • Disadvantages of Java – TheServerSide.com

CATEGORIES

  • C#
  • C++
  • Java
  • JavaScript
  • Python
  • Swift

© 2022 Copyright Learning Code

No Result
View All Result
  • Home
  • JavaScript
  • Java
  • Python
  • Swift
  • C++
  • C#

© 2022 Copyright Learning Code

Are you sure want to unlock this post?
Unlock left : 0
Are you sure want to cancel subscription?