{"id":20632897,"url":"https://github.com/jdevuyst/dustpan","last_synced_at":"2026-06-06T15:04:04.913Z","repository":{"id":70503751,"uuid":"255034387","full_name":"jdevuyst/dustpan","owner":"jdevuyst","description":"Swift mark-and-sweep garbage collector","archived":false,"fork":false,"pushed_at":"2020-05-24T09:45:36.000Z","size":13,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-15T23:56:54.380Z","etag":null,"topics":["garbage-collector","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jdevuyst.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-04-12T07:51:23.000Z","updated_at":"2021-11-16T11:45:04.000Z","dependencies_parsed_at":"2023-03-11T08:41:54.697Z","dependency_job_id":null,"html_url":"https://github.com/jdevuyst/dustpan","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jdevuyst/dustpan","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jdevuyst%2Fdustpan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jdevuyst%2Fdustpan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jdevuyst%2Fdustpan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jdevuyst%2Fdustpan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jdevuyst","download_url":"https://codeload.github.com/jdevuyst/dustpan/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jdevuyst%2Fdustpan/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33986904,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-06T02:00:07.033Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["garbage-collector","swift"],"created_at":"2024-11-16T14:17:45.035Z","updated_at":"2026-06-06T15:04:04.858Z","avatar_url":"https://github.com/jdevuyst.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Dustpan\n\nDustpan is a small library that adds optional garbage collection to Swift.\n\n## Rationale\n\nOne of the features that sets the [Swift programming language](https://swift.org) apart from other languages is its use of [Automatic Reference Counting (ARC)](https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html). Many other modern programming languages use [Garbage Collection (GC)](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)) instead.\n\nBoth ARC and GC are forms of automatic memory management. Memory that is no longer reachable from the running application is automatically freed. However, ARC has a limitation in that it cannot free [object graphs](https://stackoverflow.com/questions/2046761/what-is-object-graph-in-java) that contain [strong reference cycles](https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html#ID52). In ARC, such cycles must be broken manually.\n\nWhereas ARC has its advantages (e.g. deterministic performance), there are problem domains where GC is very handy. Consider, for example, the case where you want to [transpile](https://www.stevefenton.co.uk/2012/11/compiling-vs-transpiling/) a garbage collected programming language to Swift.\n\n## Performance\n\nDustpan was developed entirely in Swift and uses the Swift reflection API to walk the object graph. The specific GC algorithm used is [Mark and Sweep](https://www.geeksforgeeks.org/mark-and-sweep-garbage-collection-algorithm/).\n\nDustpan is mostly a toy project and its real world performance has not been analyzed. It should be expected to be quite slow.\n\n## Usage\n\nHere's an example:\n\n```swift\nimport Dustpan\n\nclass LL\u003cT\u003e {\n    var value: T\n\n    @Ref\n    var next: LL\u003cT\u003e?\n\n    init(_ value: T, _ next: LL\u003cT\u003e? = nil) {\n        self.value = value\n        self.next = next\n    }\n}\n\nclass MyApp {\n    @Ref(root: true)\n    var list: LL\u003cInt\u003e? = nil\n\n    func makeCyclicList() {\n        let last = LL(4)\n        let first = LL(1, LL(2, LL(3, last)))\n        last.next = first\n        list = first\n    }\n}\n```\n\nThere are three steps to adopting Dustpan:\n\n1. Use a `Ref(root: true)` annotation to flag object graphs that should be garbage collected.\n2. Inside the garbage collected object graphs, use a `Ref` annotation to break strong reference cycles.\n3. Periodically, call `gc()` to free unreachable memory.\n\nDo note that:\n\n- Dustpan uses a [stop-the-world algorithm](https://stackoverflow.com/questions/40182392/does-java-garbage-collect-always-has-to-stop-the-world). Therefore, while `gc` is running, there should be no mutations in the object graphs that are reachable from root references.\n- If you run into a “Fatal error: Unexpectedly found nil while unwrapping an Optional value” inside a `Ref`, this means that `gc` freed that particular `Ref` because there was no `Ref(root: true)`  pointing to that part of the program. The fix is to add the missing `Ref(root: true)` annotation.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjdevuyst%2Fdustpan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjdevuyst%2Fdustpan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjdevuyst%2Fdustpan/lists"}