[swift-users] Memory management without ARC?
Joe Groff
jgroff at apple.com
Sat Jan 30 12:12:54 CST 2016
> On Jan 30, 2016, at 7:17 AM, Matthias Zenger via swift-users <swift-users at swift.org> wrote:
>
> Hi everyone,
>
> I'm currently writing a Scheme interpreter in Swift. My original plan was to use Swift's memory management to handle objects in Scheme. Unfortunately, Scheme's data structures are inherently cyclic and I'm struggling to find a good approach to manage memory via ARC.
>
> An example that highlights the problem are arrays that contain elements that refer to the array itself. In Scheme, such arrays can be easily created like this:
>
> (define vec (vector 1 2 3))
> (vector-set! vec 1 vec)
>
> Vector vec now refers to itself via index 1.
>
> For representing a Scheme array, my interpreter simply uses an object that wraps a Swift array. The array elements point at Scheme objects. So, they could point at the array itself. Since I don't want to loose objects that are linked off the array only, I need to use strong references in the array. Obviously, this creates a serious memory leak. Here's some code illustrating the design and the construction of vec:
>
> enum SchemeValue {
> case Nil
> case Num(Int)
> indirect case Cons(SchemeValue, SchemeValue)
> case Vector(WrappedArray<SchemeValue>)
> }
>
> class WrappedArray<T> {
> var array: [T]
> init(_ elem: T...) {
> self.array = elem
> }
> }
>
> let wa = WrappedArray<SchemeValue>(.Num(1), .Num(2), .Num(3))
> let vec = SchemeValue.Vector(wa)
> wa.array[1] = vec
>
> I haven't found a good way to address the issue. What I would ideally need is manual access to retain/release functions. I would also be willing to write my own memory manager for such objects, but also this seems to be impossible in Swift. As a workaround, I currently built a mark/sweep garbage collector for all Scheme objects I allocate (by keeping them all in a weak object pool — also hand-written because it doesn't exist in Swift). But I consider this application-specific garbage collector that runs on top of ARC a huge heck.
>
> So, my question is: What are Swift programmers supposed to do if they are dealing with inherently cyclic data structures that cannot be broken up via weak references? It almost seems like there's some memory management functionality missing in Swift that makes this possible.
Doing your own GC is probably the best you can do today. You can manually retain and release references to Swift classes using the Unmanaged<T> type, which might help interoperate Swift ARC objects with your GC.
-Joe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20160130/d757a3b6/attachment.html>
More information about the swift-users
mailing list