如何通过慢慢消耗内存来识别内存泄漏

时间:2017-02-06 14:44:19

标签: macos memory-leaks

我写了一个小应用程序,每隔几秒钟调用一次文件夹。我为appr运行这个应用程序。一周。现在我看到它占用了32 GB的物理8 GB RAM。所以系统迫使我阻止它。 因此,应用程序似乎非常缓慢地占用内存。我试过仪器。使用活动监视器,唯一缓慢增长的过程是" DTServiceHub"。这是我要看的东西吗? 为了调试,我将一些信息写入标准输出。此信息是否被删除,因为应用程序是Cocoa应用程序或存储在某个地方直到应用程序终止?在这种情况下,我必须删除所有这些打印语句。

一些循环代码:

func startUpdating() {
    running = true
    timeInterval = 5
    run.isEnabled = false

    setTimer()
}

func setTimer() {
    timer = Timer(timeInterval: timeInterval, target: self, selector: #selector(ViewController.update), userInfo: nil, repeats: false)
    RunLoop.current.add(timer, forMode: RunLoopMode.commonModes)
}

    func update() {
        writeLOG("update -Start-", level: 0x2)
...
        setTimer()
    }

2 个答案:

答案 0 :(得分:1)

问题是你的应用程序永远循环,因此永远不会耗尽自动释放池。你永远不应该写这样的应用程序。如果您需要定期检查某些内容,请使用NSTimer。如果您需要了解文件夹中的更改,请使用NSWorkspace或kqueue或类似内容。换句话说,使用回调。永远不要只是循环

答案 1 :(得分:1)

您的代码存在一些问题。您应该创建一个Timer,然后在每次设置时将其添加到运行循环中,因为运行循环将保留该Timer并且永远不会释放它。更糟糕的是,每次更新时都会尝试这样做。只需创建一次计时器。如果您不再需要它,则必须使其无效以将其从运行循环中移除并允许其释放。如果您需要调整它,只需设置下一个开火日期。

以下是在操场上测试的示例:

import Cocoa

class MyTimer
{
    var fireTime = 10.0
    var timer:Timer

    init()
    {
        self.timer = Timer.scheduledTimer(timeInterval: fireTime, target: self, selector: #selector(update), userInfo: nil, repeats: true)
    }

    deinit
    {
         // it will remove the timer from the run loop and it will enable its release            
         timer.invalidate()
    }

    @objc func update()
    {
        print("update")
        let calendar = Calendar.current
        let date = Date()

        if let nextFireDate = calendar.date(byAdding: .second, value: Int(fireTime), to: date)
        {
            print(date)
            timer.fireDate = nextFireDate
        }
    }
}

let timer = MyTimer()

CFRunLoopRun()