[swift-users] hello world takes almost 1MB of RAM

Nadav Rotem nrotem at apple.com
Fri Mar 4 16:43:16 CST 2016


Hi Karl, 

> On Mar 4, 2016, at 1:30 PM, Karl Pickett via swift-users <swift-users at swift.org> wrote:
> 
> On ubuntu 14.4, 
> $ swiftc -v
> Swift version 3.0-dev (LLVM b361b0fc05, Clang 11493b0f62, Swift 24a0c3de75)
> Target: x86_64-unknown-linux-gnu

Thanks for reporting this. 

> 
> Sample program, compiled with simply "swiftc t.swift".
> 
> $ cat t.swift 
> import Foundation
> print("hello, world\n")
> while true {
>     sleep(1)
> }

> 
> pmap -XX <pid> shows me 4870KB RSS, 880KB of which is private dirty / anonymous.  So every additional copy you start takes 880KB of RAM.   (Our use case has thousands of processes running)

I compiled your program on my mac and I am seeing different numbers. On my machine, "vmmap -dirty” reports ~120K of dirty memory. I wonder why there's a big difference between Mac and Linux.

Swift has memory overhead that’s related to caching of protocol conformances and generic metadata. Basically, Swift does not recompute type properties and does not check protocol conformances over and over again, because these operations are expensive in terms of runtime. Instead, Swift maintains a cache. 

The ‘print’ function is a pretty big function, so in order to reduce code size in the user app we decided to keep ‘print' in the standard library and not clone-and-optimize it into every single user app. The problem is that the optimizer can’t clone-and-specialize print, so print has to work with generic types. When swift works with generic types it has to access generic metadata and allocate memory for this metadata. 

Let’s try to figure out what’s taking all the memory. Try placing a breakpoint in “main”, and then after you stop at main you can place another breakpoint in “malloc”. This will allow you to separate between allocations that happen before ‘main’ and allocations made by Swift. On my machine I am seeing allocations that come from “swift_getExistentialTypeMetadata”, “swift_getGenericMetadata”, and “swift_conformsToProtocol”. This is expected. Are you seeing other memory allocations?

Why are you running thousands of processes?  What are you trying to build? 

> 
> For compariso:
> - a dynamically linked C/glibc program takes 88KB
> - a dynamically linked C++/glibc,libstdc++ program takes 172KB
> - a statically linked C++/glibc,libstdc++ program takes 64KB
> - a statically linked musl c program takes just 16KB
> 
> Is this on the roadmap for improvement?  

Yes, we would like to reduce Swift’s memory usage, but there is no plan to remove the protocol conformance/metadata caches. 

Thanks,
Nadav

> 
> - Karl
> 
> 
> 
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users



More information about the swift-users mailing list