ghc-mod
ghc-mod copied to clipboard
ghc-mod eating up my memory
I have a cabal project with happy/alex parser rules. (https://github.com/TOSPIO/pyn) After I opened the project with either Emacs or Atom, and opened arbitrary source files, it rapidly ate up my whole memory (16GiB) and eventually led to kernel panic.
One thing to notice is that running cabal repl
can also exhaust memory. cabal build
works fine, though compiling the Happy-generated hs file takes fairly long time.
This is a bug in either your code, happy or GHC, certainly not ghc-mod since cabal repl
exhibits the exact same behavior. Looking at the enormous generated module for the parser (dist/build/Language/Python/Parser/Parse.hs) I'm not really surprised.
https://ghc.haskell.org/trac/ghc/wiki/ReportABug
By giving -fobject-code
to ghc, and furtherly adding ghc-options: -fobject-code
in pyn.cabal
file,
cabal repl
works fine.
However, running ghc-mod -g "-fobject-code" browse -d Language.Python.Pyn.Visit
still uses up memory.
It can be a GHC bug (I've made a bug report). But since there's this way to workaround the issue for GHCi and Cabal, I wonder if it's also possible for ghc-mod.
Mind linking me to the GHC report?
@DanielG https://ghc.haskell.org/trac/ghc/ticket/11380
I'm fairly new to Haskell so I'm probably not capable to do very in-depth troubleshooting. But hopefully I can provide more information if needed.
After adding -fobject-code to both the executable and library sections in your cabal file ghc-mod check dist/build/Language/Python/Pyn/Parser/Parser.hs
works just fine, I can't check browse since thats giving me an unrelated error.
FWIW, this may be relevant. Potentially the editor is trying to cope with very long lines. https://github.com/simonmar/alex/issues/84
I don't think so this happens when running ghc-mod without any frontend.
In my case, ghc-mod gradually uses all the available memory (see attached screenshot). It might take days but eventually it exhausts all RAM. My project uses cabal and depends on Parsec and Hoopl. I use ghc-mod from emacs.
You really shouldn't be leaving it running for that long in the first place, but an easy fix would be to just kill the process every once in a while. It will then be restarted as needed when you actually run any commands that needs it.
Here's a quick prototype of that in Elisp. It uses an idle timer so when you don't use Emacs for 7200 seconds (2h) it will kill the process. (obviously you can change the timeout to whatever suits you)
(see below)
Minor revision, you'd also want to kill the timer when the buffer is killed:
(defvar my-ghc-idle-kill-timer
"Timer used to kill ghc-mod process when Emacs is idle for a long time.")
(defun my-ghc-init-whith-idle-kill ()
(ghc-init)
(make-variable-buffer-local 'ghc-idle-kill-timer)
(setq ghc-idle-kill-timer (run-with-idle-timer 7200 t 'ghc-kill-process))
(add-hook 'kill-buffer-hook '(lambda () (cancel-timer ghc-idle-kill-timer))))
(add-hook 'haskell-mode-hook (lambda () (my-ghc-init-whith-idle-kill)))
Thank you for the code.
Didn't know that I was supposed to kill the process periodically.