Closed stardiviner closed 5 years ago
It's supposed to define a single timer which get's repeatedly run a few times per second. Are you sure you're seeing many different timers? Or could it be a single timer running many times?
Also, it's worth mentioning that aggressive-indent doesn't seem to be the cause for your slow-downs according to your profiling (though maybe you already knew that).
Yes, about the profiling result, I already know aggressive-indent is not the cause.
From the screenshot, I can't figure out it is different timers or single timer running many times. It cloud be many timers on many different buffers.
I don't know if this is related but I'll put it here since I have so very little to add:
After having run my Emacs continuously for a couple of weeks, opening somewhere around 10–50 files each day, and continuously cleaning up my open buffers, I noticed interaction became really slow. I looked into the CPU profiler report, and cancel-timer-internal consumed nearly 75% of the time.
I don't actually know whether this is aggressive-indent leaking timers, because my way of trying to see where the timers came from was to insert (error)
into cancel-timer-internal and look at the stack trace. The first error came right away, and belonged to aggressive-indent-mode. Then Emacs locked up over all the errors it had to handle, so I had to restart it and the problem went away.
This is very unreliable information, but in the unlikely case it helps someone, there it is.
I'm not 100% sure whats going on here. Aggressive-indent does create a separate idle timer for each buffer, but this timer is canceled as soon as its function finishes running. So they shouldn't stick around for more than a second.
Maybe it's a consequence of the buffer being deleted, then the idle timer keeps trying to run, but never actually finishes, so it never gets canceled.
I suppose using just a single global timer might help. I've pushed a commit doing that now, so we can test on melpa unstable. Let me know if it works for y'all.
Maybe it's a consequence of the buffer being deleted, then the idle timer keeps trying to run, but never actually finishes, so it never gets canceled.
I think this is very possible. I will try out the latest and report here.
Seems MELPA not fetched the updated aggressive-indent yet. check it out later.
Using the latest aggressive-indent-mode I can report I don't seem to have experienced any regressions from that change.
There is a regression from that change as evidenced in #121.
Maybe it's a consequence of the buffer being deleted, then the idle timer keeps trying to run, but never actually finishes, so it never gets canceled.
If you think that's the case, why don't you do this instead?
diff --git a/aggressive-indent.el b/aggressive-indent.el
index da21bfe..ea8e9c1 100644
--- a/aggressive-indent.el
+++ b/aggressive-indent.el
@@ -417,6 +417,8 @@ typing, try tweaking this number."
(defun aggressive-indent--indent-if-changed ()
"Indent any region that changed in the last command loop."
+ (unless (buffer-live-p (current-buffer))
+ (cancel-timer aggressive-indent--idle-timer)
(when (and aggressive-indent-mode aggressive-indent--changed-list)
(save-excursion
(save-selected-window
Alright, I'm trying an alternative version of that. Feedback is appreciated, specially with regards to whether it breaks this issue again.
I'm on the latest version but this issue still keeps cropping up now and again, usually I notice it when lag starts increasing a lot, opening list-timers
and finding that there are several hundred aggressive-indent--indent-if-changed
entries.
Here's a quick hack I came up with to automate that process and monitor when it happens, I have a hunch that it's related to evil-mc
but can't reliably reproduce the context to trigger it.
(defun cancel-aggressive-indent-timers ()
(interactive)
(let ((count 0))
(dolist (timer timer-idle-list)
(when (eq 'aggressive-indent--indent-if-changed (aref timer 5))
(incf count)
(cancel-timer timer)))
(when (> count 0)
(message "Cancelled %s aggressive-indent timers" count)))
(run-with-timer 60 nil 'cancel-aggressive-indent-timers))
@yuhan0 Are you sure you meant
(run-with-timer 60 nil 'cancel-aggressive-indent-timers)
and not
(run-with-timer 60 60 'cancel-aggressive-indent-timers)
(I experienced this issue again, now, and started wondering why running cancel-aggressive-indent-timers
manually canceled 3000 timers – and I had never seen it running automatically!)
When I found Emacs suddenly have high CPU usage even I did nothing. Then I try to check out Emacs idle timers with
[M-x list-timers]
. I toke an screenshot:Here is the result:
I found
aggressive-indent-mode
created so many timers. Why? Is it normal? Here is my config: