需要帮助来消除连续的内存泄漏...没有被引用

时间:2019-12-28 17:18:46

标签: swift macos cocoa memory-leaks swiftui

我创建了一个与Terraria Mod协同工作的应用程序。该mod通过TCP将清单更新作为JSON对象发送到应用程序,然后在触摸栏中显示清单。

我遇到的问题是,一旦收到更新,就会有连续的内存泄漏,随着时间的流逝,这些泄漏总计达数百MB。这会减慢应用程序的运行速度。

复制self时,我发现的内存泄漏之一发生在下面的第二行代码中:

func scaleEffect(_ scaleMultiplier: CGFloat, maxLength: CGFloat = .infinity) throws -> NSImage {
    guard let image = self.copy() as? NSImage else {
        throw RuntimeError.error("Error copying image")
    }
    image.size.width *= scaleMultiplier
    image.size.height *= scaleMultiplier
    if image.size.width > maxLength || image.size.height > maxLength {
        let ratio = image.size.width / image.size.height
        let const: CGFloat = maxLength
        if image.size.width >= image.size.height {
            image.size.width = const
            image.size.height = const / ratio
        } else {
            image.size.height = const
            image.size.width = const * ratio
        }
    }
    return image
}

我什至不知道为什么会泄漏内存,但这只是发生的许多泄漏之一!

另一个使我感到困惑的内存泄漏是,一个_ContiguousArrayStorage<DisplayList.Item>实例的实例泄漏。我不知道这个类是什么,也不知道它的专业化类型是什么。我所知道的是,我有一个名为Item的课程,仅此而已。这种特定的泄漏似乎确实引用了大多数其他泄漏的对象,但是它自己的内存图看起来像这样:

Leaked _ContiguousArrayStorage<DisplayList.Item> instance memory graph

我知道...令人困惑,对吧?

您可以找到应用程序的GitHub存储库here。我创建了一种无需模版就可以发送清单更新的方法,如here所述。

谢谢。


编辑:

我已经追踪到大多数内存泄漏是由于使用了上面声明的nsImage.scaleEffect(_ scaleMultiplier:, maxLength:)方法。在下面的评论中,Rob提到他注意到,如果您删除了ObservableTimer中用于脉动的StatsView实例,泄漏就会减少。

经过进一步的试验,我意识到这意味着仅在状态更改和SwiftUI视图重新加载后才创建泄漏,因为再次调用了上述方法。

如果您删除this line中的, let scaledImage = try? image.scaleEffect(spriteScaleMultiplier, maxLength: maxSpriteLength)并将this line中的scaledImage更改为image,则泄漏会再次减少。

在评论StatsView的任何初始化时,我只调查了InventoryView,但是InventoryView实例包含ItemView实例,也称为上述方法。

TL; DR:我提到的第一种方法比Phil Swift在 EXTREME BUCKET DEMO 中破坏的那个桶更易泄漏,但是我仍然需要帮助找到FLEXSEAL®来解决泄漏! (老模因,但是这已经是十年的末日了……)。

0 个答案:

没有答案