Memory Issue when repeating a "Type a Keystroke" command

The loop version from here (Memory Issue when repeating a "Type a Keystroke" command - #16 by ericv) runs in about 40 seconds and didn't cause any buffering or UI issues in Sublime text editor.

But as noted here (Memory Issue when repeating a "Type a Keystroke" command - #9 by ericv) even if I set the delay to 1 second (which is huge for a simple keypress macro), if I walk away it continues to build up the shared memory usage until the system becomes unresponsive.

Appreciate you trying it! Did ending the macro and letting the buffer finish free up the memory? In my experience, the only way to free that shared memory is to restart KM Engine. I have left it for hours hoping for some trash collection or something to grab it, but it never cleans itself up.

Yeah, I've just plonked BBEdit onto my test machine and that reacts a lot more quickly than Script Editor, with no visible buffering. Edit to add: That was on a short test -- on a longer run -- 100,000+ characters -- or, perhaps, as memory use climbs, buffering becomes apparent.

That doesn't mean it isn't buffering, though! IIRC the system's Events buffer is pretty limited and so the Script Editor test suggests there's buffering in KM (which would explain the climb in memory usage). 150-200 keystroke events per second is somewhat beyond "emulating normal user interaction", so I'm not surprised we don't usually notice it!

My (very basic!) understanding of "modern" memory management is that apps don't need to "free" unused memory until they exit or the OS grabs it back for use elsewhere. So my hope was that running the macro repeatedly would keep re-using that extra buffer space. Unfortunately not -- it keeps adding to it.

Hmmm... 1GB of memory use is ~65,000 characters, ie 2^16 -- that's a very computery number and, perhaps, a clue...

I've got to ask again -- how many keypresses do you actually need? While this is a fun exercise, and I'm happy to keep poking, my 8GB Air has managed to type 500,000+ ls into BBEdit with no sign of stopping... That's an excessive amount of keypressing for even the worst no-lifer game routine!

This is exactly why I only noticed it recently. I've been using KM for years and always blamed it on the game or the system not being restarted (which are probably issues as well - but...)

The keypresses actually come in groups. Usually a bunch of them for a limited amount of time. "Do this thing for 10 minutes while I run to the restroom." or "Click this thing for 20 minutes while I grab some food."

My expectation was that, even if the memory went up, when I stopped the macro it would free it and then I could go again. It wasn't until I started digging deeper that I realized it was KM.

The main thing that makes me go :thinking: is that using the Applescript, while slower, doesn't seem to cause the shared memory increase. Maybe it is just moving that shared memory issue to another place that I am not seeing it, but it seemed odd.

I will look at this again, but as referenced in the other thread, there does not appear to be a memory leak in Keyboard Maestro per se, but memory used by the system increases.

AppleScript might behave differently for any number of reasons - for one thing that is Apple’s code doing the work, and they could use any number of different, private APIs for the purpose.

As far as the connection failing issue, AppleScript is run through osascript, which is executed in a subprocess, and then likely requires some for of inter-application communication as well. Anything that executes large numbers of subprocesses in quick succession, or connections in quick succession, is likely to run out of some sort of needed resource that is periodically cleaned up by the system (such as process/connection ids or ports, process/connection table space, etc). This is likely what is happening.

You might like to try instead running a single AppleScript that continuously sends the keystrokes. Then have it check whether to continue. Possibly use the existence of a temporary file (eg "/tmp/stopnow") as a single to stop so there is no direct inter-application communication required.

Interesting. I'll give that a try. I may also try stuffing the results into a variable and if it's not a success, try again, since it seems to recover pretty quickly. :thinking:

I was hoping to have another data point for you, @ericv, but my laptop's still processing "queued" keypresses even though the macro stopped a day ago...

BBEdit's document window has recorded 1.2 million characters so far, KME is reported as using 32GB of memory (on an 8GB machine), and nothing's crashed. You said in your OP that "the entire system hangs" -- I'm wondering if it actually has hung or if it is unresponsive because of processing the "queued" events.

I doubt you'll be sending such an extreme number of keypresses during a 20 minute break to grab some food so, if @peternlewis's "external" AppleScript solution doesn't help, perhaps you can get away with an action at the end of your keypress macro that flushes the memory by quitting and relaunching KME. I'm thinking an async AppleScript that checks KME memory allocation and if that's over eg 1GB waits until no macros are running and then quits and opens the Engine app.

1 Like

Can you share the macro you used for this? Interested why your KM Engine isn't bloating shared memory.

Oh, but it is -- that's around 450GB reported! And still not crashing... But shared climbs proportional to the KME allocation reported in Activity Monitor or top, and those are much easier numbers to get for a scripted "shall will kill it yet?", which is why I mentioned it.

The macro is the same as your first posting, minus the logging and pause actions.

Oh. I misunderstood. I thought you said it was only reporting 32GB, which is essentially fresh launch memory.

Read it again -- 32GB, not MB. If your KME is taking 32GB at launch you've got real problems...

2 Likes

You are correct. I misread. :slight_smile:

As a little closure to this thread, using Applescript appears to prevent the memory increases (or at least slows them to the point of not being an issue), however there are cases where multiple applescripts in succession will fail. They do seem to recover if run again immediately and they don't appear to compound, so if the keypress is important, something simple like the below appears to work (will fire the applescript until success - which in most cases is immediate or until the cmd key is held down - to give you an out):

Screen Shot 2022-08-09 at 9.40.18 AM

Beyond that, I've created an automator app to restart the KM engine and bound that to my "cancel all macros" (oh $h1t button). So, every now and then throughout the day, I just ctrl+cmd+shift+x and when the engine restarts (it only takes about a second), it frees up any floating shared memory.

Screen Shot 2022-08-09 at 9.36.52 AM

Appreciate everyone that looked into this. This community is awesome, and I honestly don't know what I'd do without KM. It makes my life so much more efficient.

Thanks all!!