Sun, 8 Oct 2017 #
Taming SourceKitService for Less Xcode Memory Consumption
1 Update [10/15/2017]
<a href="https://t.co/aJc8ZZSm9c">It seems that Xcode 9.1 beta 2 fixes this issue.</a>
In my preliminary testing, everything worked fine. This feels really good.
2 Original Article
There were recently two popular Swift posts on Hacker News1 , 2, and one issue I saw coming up multiple times was the memory consumption of the tooling nee Xcode. One particular problem is that for some codebases the Swift sourcecode process SourceKitService
consumes a huge amount of memory. I've had it rise to 30GB and beyond - at which point my system usually stalls and I'm not able to continue working for a couple of minutes.
Oftentimes memory issues like these can be solved by reviewing your sourcecode with the same tools you also use to reduce your compile times. See:
- https://www.jessesquires.com/blog/measuring-compile-times-xcode9/
- https://www.swiftbysundell.com/posts/improving-swift-compile-times
However, for some, complex, codebases this may not be enough. I've employed an awful little hack in order to at least keep my machine from stalling. I wrote a small little bash script that check the memory consumption of the SourceKitService
every n
seconds and if it goes beyond x
megabytes of memory (by default 5.000) I restart it. I feel that this may be useful to some others so I'm sharing it here for posterity. Note that this is an awful hack and future versions of SourceKitService
will probably (hopefully!) not need this anymore. Meanwhile, this might be of help to others:
#!/bin/bash # Amount of seconds to wait between measures n=1 # Limit memory consumption to this many megabytes before killing the process x=5000 name="SourceKitService" while true; do fields=`ps aux -m | grep -v grep | grep -i $name | tr -s ' '` mem=`echo $fields | cut -d ' ' -s -f 6| awk '{$1=$1/1024; print $1;}' | cut -d '.' -f 1` pid=`echo $fields | cut -d ' ' -s -f 2` if [ -z "$mem" ]; then echo "$name not running" sleep 15 continue fi if [ "$mem" -gt $x ]; then echo "Killing $name pid $pid with mem $mem" kill -9 $pid sleep 5 fi sleep $n done
To use this just paste that code into a file (say sourcekill.sh
) and do:
chmod +x ./sourcekill.sh ./sourcekill.sh
If you want to kill it, just hit CTRL=C
.
Footnotes:
If you read this far, you should follow me (@terhechte)
on Twitter