Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix "Your system has run out of application memory" bug #1341

Closed
latenitefilms opened this issue Jun 28, 2018 · 23 comments
Closed

Fix "Your system has run out of application memory" bug #1341

latenitefilms opened this issue Jun 28, 2018 · 23 comments
Assignees
Labels
Milestone

Comments

@latenitefilms
Copy link
Contributor

No description provided.

@latenitefilms
Copy link
Contributor Author

As discussed on Facebook @randomeizer - I THINK this might have something to do with cp.app.prefs:prop() watchers triggering repeatedly when nothing has actually changed.

@latenitefilms
Copy link
Contributor Author

I'm going to close this issue for now as it's too broad.

@latenitefilms
Copy link
Contributor Author

Kevin reports:

Before:

b4

After Force Quitting:

after

@latenitefilms
Copy link
Contributor Author

The highlighted values are constantly increasing, even with Final Cut Pro closed:

screen shot 2018-08-13 at 10 49 21 pm

@latenitefilms
Copy link
Contributor Author

This is what happens when I click the little arrow icon next to the _NSArrayM item:

screen shot 2018-08-13 at 10 51 28 pm

@latenitefilms
Copy link
Contributor Author

Before opening Final Cut Pro:

screen shot 2018-08-13 at 10 55 35 pm

After opening and using Final Cut Pro:

screen shot 2018-08-13 at 10 57 17 pm

@latenitefilms latenitefilms reopened this Aug 13, 2018
@latenitefilms
Copy link
Contributor Author

screen shot 2018-08-13 at 11 00 14 pm

screen shot 2018-08-13 at 11 03 18 pm

screen shot 2018-08-13 at 11 05 30 pm

@randomeizer
Copy link
Contributor

What are you gleaning from this?

@latenitefilms
Copy link
Contributor Author

screen shot 2018-08-13 at 11 14 53 pm

screen shot 2018-08-13 at 11 16 54 pm

@latenitefilms
Copy link
Contributor Author

I left my computer running overnight with CommandPost running via the Leaks Instrument in Xcode, and Final Cut Pro playing a timeline on loop whilst also running the following code:

chaosTimer = hs.timer.doEvery(30, function()
	 _fcp:inspector():show()
	 hs.timer.doAfter(5, function()
	 	_fcp:inspector():hide()
	 end)
end)

When I came back to it 04:56:35 later, I was presented with the dreaded "Out of application memory" error - although Activity Monitor looked fine - but Xcode Instruments had stopped because "An error occurred trying to capture Leaks data - Error retrieving leak information".

Here's a photo of what my computer looked like when I came back to it:

img_1781

Here's what Instruments showed:

screen shot 2018-08-14 at 7 37 39 am

screen shot 2018-08-14 at 7 37 14 am

@latenitefilms
Copy link
Contributor Author

screen shot 2018-08-14 at 7 49 32 am

@latenitefilms
Copy link
Contributor Author

Probably not related - but FYI:

screen shot 2018-08-14 at 8 06 49 am

screen shot 2018-08-14 at 8 06 47 am

screen shot 2018-08-14 at 8 06 45 am

@latenitefilms
Copy link
Contributor Author

Leak from Kevin on 19th June:

untitled

@latenitefilms
Copy link
Contributor Author

Leak from Kevin on 21st June:

memory

quit-commandpost

@latenitefilms
Copy link
Contributor Author

Leak from Kevin on 13th July:

commandpost

@latenitefilms
Copy link
Contributor Author

Leak from Kevin on 13th July:

commandpost-b4

commandpost-after

@latenitefilms
Copy link
Contributor Author

@cmsj - As suggested, I left my computer running overnight with CommandPost running via the Leaks Instrument in Xcode, and Final Cut Pro playing a timeline on loop whilst also running the following code:

local timer = require("hs.timer")
local fcp = require("cp.apple.finalcutpro")
chaosTimer = timer.doEvery(30, function()
	fcp:inspector():show()
	timer.doAfter(5, function()
		fcp:inspector():hide()
	end)	 
	local file = io.open("/Users/chrishocking/Desktop/CommandPost.log", "a")
	io.output(file)
	io.write(os.date() .. " - " .. collectgarbage("count") .. "\n")
	io.close(file)
end)

For this test, I also disabled the AX cache, by adjusting:

function axutils.cache(source, key, finderFn, verifyFn)
    local value = source and source[key]
    if value == nil or not axutils.isValid(value) or verifyFn and not verifyFn(value) then
        value = finderFn()
        if axutils.isValid(value) and source then
            -- Don't cache.
            --source[key] = value
        else
            return nil
        end
    end
    return value
end

The log file I was writing to the Desktop ended up as follows:

Wed Aug 15 23:35:43 2018 - 34016.487304688
Wed Aug 15 23:36:25 2018 - 46473.979492188
Wed Aug 15 23:37:02 2018 - 51819.454101562
Wed Aug 15 23:37:40 2018 - 40086.653320312
Wed Aug 15 23:39:19 2018 - 56778.796875
Wed Aug 15 23:40:20 2018 - 79220.682617188
Wed Aug 15 23:40:55 2018 - 49283.708007812
Wed Aug 15 23:41:15 2018 - 60838.08203125
Wed Aug 15 23:41:54 2018 - 70667.78125
Wed Aug 15 23:43:35 2018 - 85593.2109375
Wed Aug 15 23:44:52 2018 - 95993.771484375
Wed Aug 15 23:45:13 2018 - 50060.25
Wed Aug 15 23:46:22 2018 - 59470.7890625
Wed Aug 15 23:46:54 2018 - 76264.412109375
Wed Aug 15 23:47:20 2018 - 84014.870117188
Wed Aug 15 23:49:39 2018 - 99457.670898438
Wed Aug 15 23:50:42 2018 - 102134.66503906
Wed Aug 15 23:53:29 2018 - 58178.86328125
Thu Aug 16 00:07:48 2018 - 104832.80957031
Thu Aug 16 00:15:05 2018 - 73225.069335938
Thu Aug 16 00:31:25 2018 - 112716.94628906
Thu Aug 16 00:45:18 2018 - 89645.551757812
Thu Aug 16 01:08:30 2018 - 113587.12792969
Thu Aug 16 01:58:38 2018 - 130937.41699219
Thu Aug 16 02:14:50 2018 - 135066.65136719
Thu Aug 16 02:20:58 2018 - 154472.53222656
Thu Aug 16 02:30:12 2018 - 85716.178710938

At the start of the test:

screen shot 2018-08-15 at 11 41 22 pm

screen shot 2018-08-15 at 11 41 22 pm 2

At the end of the test:

screen shot 2018-08-16 at 5 53 33 am

screen shot 2018-08-16 at 5 53 33 am 2

screen shot 2018-08-16 at 5 54 20 am

screen shot 2018-08-16 at 5 54 50 am

screen shot 2018-08-16 at 5 56 20 am

@latenitefilms
Copy link
Contributor Author

latenitefilms commented Aug 16, 2018

I know @randomeizer is sick of my screenshots, but here's another set.

This is on one of our iMac's.

All of a sudden, the Mac will popup the out of application memory error - notice the memory pressure graph and application memory value:

screen shot 2018-08-16 at 12 14 40 pm

CommandPost is still accessible, so I run some garbage collection commands - it doesn't really help:

screen shot 2018-08-16 at 12 16 34 pm

However, when I gracefully quit CommandPost, everything goes back to normal:

screen shot 2018-08-16 at 12 16 57 pm

It seems like "kernel_task" is the biggest memory hog - but I'm not sure why or how it's connected.

Before & After:

before and after

@latenitefilms
Copy link
Contributor Author

Note to self - another test. This time just running CommandPost normally - without Xcode Instruments.

Before:

screen shot 2018-08-17 at 12 16 25 am

During:

screen shot 2018-08-17 at 12 28 27 am

After:

screen shot 2018-08-17 at 6 19 59 am

Garbage Collection Count values:
https://gist.github.com/latenitefilms/1ccb2f32fb8de13751a0423c9916906d

@latenitefilms
Copy link
Contributor Author

An earlier test...

Before:

screen shot 2018-08-16 at 10 48 38 pm

screen shot 2018-08-16 at 10 48 38 pm 2

During:

screen shot 2018-08-16 at 11 19 58 pm

screen shot 2018-08-16 at 11 19 58 pm 2

First Sign of Trouble:

screen shot 2018-08-16 at 11 30 08 pm

screen shot 2018-08-16 at 11 30 08 pm 2

Just before CommandPost quit:

screen shot 2018-08-16 at 11 30 49 pm

screen shot 2018-08-16 at 11 30 49 pm 2

@latenitefilms latenitefilms changed the title Track down CommandPost Memory Leak in Beta 30 Prevent "Your system has run out of application memory" alert from appearing Aug 17, 2018
@latenitefilms latenitefilms changed the title Prevent "Your system has run out of application memory" alert from appearing Fix "Your system has run out of application memory" bug Aug 17, 2018
@latenitefilms
Copy link
Contributor Author

latenitefilms commented Aug 17, 2018

For comparison, I just left Beta 29 running all night. Unfortunately a few hours after I started it weirdly got a Lua error, which broke my test hs.timer:

> local timer = require("hs.timer")
local fcp = require("cp.apple.finalcutpro")

local file = io.open("/Users/chrishocking/Desktop/CommandPost.log", "a")
io.output(file)
io.write(os.date() .. " - " .. collectgarbage("count") .. "\n")
io.close(file)

chaosTimer = timer.doEvery(10, function()
	fcp:inspector():show()
	timer.doAfter(5, function()
		fcp:inspector():hide()
	end)	 
	local file = io.open("/Users/chrishocking/Desktop/CommandPost.log", "a")
	io.output(file)
	io.write(os.date() .. " - " .. collectgarbage("count") .. "\n")
	io.close(file)
end)

2018-08-18 01:10:56: ********
2018-08-18 01:10:56: 01:10:56 ERROR:   LuaSkin: hs.timer callback error: .../extensions/cp/apple/finalcutpro/inspector/Inspector.lua:283: attempt to index a boolean value
stack traceback:
	.../extensions/cp/apple/finalcutpro/inspector/Inspector.lua:283: in function 'cp.apple.finalcutpro.inspector.Inspector.show'
	[string "local timer = require("hs.timer")..."]:10: in function <[string "local timer = require("hs.timer")..."]:9>
2018-08-18 01:10:56: ********

FYI: This bug has already been fixed in Beta 30.

However, that aside, it still ran all night without any "Out of application memory" errors by the morning.

Before:

screen shot 2018-08-17 at 11 07 00 pm

After:

screen shot 2018-08-18 at 7 53 47 am

Here's the garbage collection test results prior to the timer failing:

https://gist.github.com/latenitefilms/37336803ea99ec6b9883f39ef083162d

@latenitefilms
Copy link
Contributor Author

Ok, so I had a minor victory last night. I made the following minor change to latest develop branch:

screen shot 2018-08-19 at 8 41 09 am

With the CommandPost Grid Viewer Overlay enabled, Scrolling Timeline enabled, and Final Cut Pro playing, I then executed the following test code:

local timer = require("hs.timer")
local fcp = require("cp.apple.finalcutpro")

local file = io.open("/Users/chrishocking/Desktop/CommandPost.log", "a")
io.output(file)
io.write(os.date() .. " - " .. collectgarbage("count") .. "\n")
io.close(file)

chaosTimer = timer.doEvery(10, function()
	fcp:inspector():show()
	timer.doAfter(5, function()
		fcp:inspector():hide()
	end)	 
	local file = io.open("/Users/chrishocking/Desktop/CommandPost.log", "a")
	io.output(file)
	io.write(os.date() .. " - " .. collectgarbage("count") .. "\n")
	io.close(file)
end)

Here's the output of the log file:
https://gist.github.com/latenitefilms/987fe5fddb37b6496f79a6dccedea3a3

Here's what everything looked like before I executed that code:

screen shot 2018-08-19 at 12 20 10 am

screen shot 2018-08-19 at 12 20 10 am 2

Here's what everything looked like when I woke up:

screen shot 2018-08-19 at 8 23 30 am

screen shot 2018-08-19 at 8 23 30 am 2

The minor victory was, that despite the fact that the memory pressure graph in Activity Monitor was looking very sad, CommandPost was still running and there was no "out of application memory" error - which is the first test this has happened for after running overnight.

I stopped the timer, then checked the garbage collection values:

screen shot 2018-08-19 at 8 39 07 am

screen shot 2018-08-19 at 8 39 07 am 2

What's most interestingly though, is that I then pressed the "Reload" button in the Error Log, and when CommandPost reloaded, the memory pressure graph went back to normal - as did the kernel_task real memory usage:

screen shot 2018-08-19 at 8 40 21 am

screen shot 2018-08-19 at 8 40 21 am 2

It seems collectgarbage("count") isn't what we should be monitoring - it's the hs.crash.residentSize() (i.e. an integer containing the amount of RAM in use by Hammerspoon in bytes).

This makes me think that the issue is still that we're creating too many AX objects (or too many AX observer objects?), that aren't being properly destroyed/released - which is why kernel_task is using up so much RAM, as I ASSUME the Accessibility Framework uses kernel tasks to do it's thing.

@latenitefilms
Copy link
Contributor Author

I'm going to close this issue for now - in the HOPE that the recent changes have fixed this issue.

Fingers and toes crossed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants