Subject: Re: bug#39413: 26.2; Emacs gets hung

From: chiaki-ishikawa-thunderbird-account <[email-masked]>
Date: Mon, 8 Jun 2020 17:17:00 +0900

On 2020/05/26 0:50, chiaki-ishikawa-thunderbird-account wrote:
> On 2020/05/25 21:15, Noam Postavsky wrote:
>> chiaki-ishikawa-thunderbird-account <[email-masked]> writes:
>>
>>> Short of lisp function, maybe I can add message print out in alloc.c
>>> to print out such information so that it gets recorded in *Message*
>>> buffer.
>>> It is done only when gabage-collection-message is t and there should
>>> be some throttling mechanism to avoid spamming the user.
>>> Any pointer re the hook(s) short of rewriting alloc.c is
>>> appreciated. Well, if worst comes to worst, I don't mind rewriting
>>> alloc.c to create an array of fixed size to store the last dozen or so
>>> GC-related information that is updated before and after invocation of
>>> a certain GC entry point.
>>> I can print that out after a long GC to learn the memory situation.
>>> But that sounds a bit drastic. OTOH, it may be the only way to go.
>> That should probably work.  I see the current
>> garbage_collection_messages code uses message_nolog, I guess because
>> growing the *Messages* buffer could also trigger GC.
>>
> Thank you, I will probably do that.
>
> Back in 18.x days, printing the message from within GC caused another 
> GC invocation, thus emacs blew up due to stack flow after so many 
> recursive calls.
>
> I think having a static array of 10-20 cells to store previous GC info 
> should work.
>
> Stay tuned. I am really interested in WHERE/WHY this long pause 
> occurs.: maybe Windows 10 memory allocation/ Virtual Box 
> emulation/Linux kernel memory allocation, and AMD Ryzen CPU's cache 
> replacement policy all add up.
>
> Chiaki
>
>
Hi,

After looking at alloc.c, I realized that there *IS* a post-hook that 
gets called after GC.

So instead of hacking and modifying alloc.c, I took the easy route and 
did the following in my .emacs
(the code is in postscript)
and now waiting for the next LOOONG gc behavior.

Basically I record some GC-related statistics for the last 10 
invocations, and make sure it is recorded in *Messages* buffer.
Maybe I can learn something from it. (My most suspicious part is string 
GC. When I run "erase-buffer" on the "*shell*" buffer which has 
accumulated a large build output a few times over, GC tends to be very 
longish.)

If you know any other easily obtainable GC-related information that 
ought to be in the statistics
on top of
(append (memory-use-counts) (list gc-elapsed gcs-done))
please let me know.

Directly evaluating (garbage-collect) prints a neat result, but I am not 
sure if that can be easily simulated from ordinary eval.
(And maybe it is only syntactic sugar and doesn't add much to the 
necessary statistical data.)

TIA

Chiaki Ishikawa

PS: The addition in my .emacs
;;;
;;; GC behavior monitor
;;;
;;; Record some key information for GC in the GC post-hook so that I
;;; can learn something about the behavior and performance of GC with
;;; concrete data.

(setq my-gc-statistics (make-vector 10 nil))

;;; The element is
;;; (append (memory-use-counts) (list gc-elapsed gcs-done))
;;; Each time the following function is called, the
;;; elements in the array is shifted toward the end.
;;; Use (message "%S" my-gc-statistics) to force the
;;; recording of my-gc-statistics value in *Messages* buffer for later 
analysis.

(defun update-my-gc-statistics ()
   (let ((i 8))
     (progn
      ;;; very unlike Lisp
      (while (<= 0 i)
        (progn (aset my-gc-statistics (+ 1 i) (aref my-gc-statistics i))
              (setq i (- i 1) )))
      (aset my-gc-statistics 0
            (append (memory-use-counts) (list gc-elapsed gcs-done)))
      (message "%S" my-gc-statistics))))

(setq post-gc-hook 'update-my-gc-statistics)