git/list[1] front-page[2] threads[3] people[4] search[5] about
wed 2026-10-07 18:11 UTC

Re: gitk: avoid obscene memory consumption

From
Markus Hitter <mah@jump-ing.de>
Date
Nov 7, 2016, 13:43 UTC
Message-ID
<3b16a0f5-46e3-b41c-553a-473ad3e9cf26@jump-ing.de>
In-Reply-To
<20161107041138.rnlzyuacoezsfwif@oak.ozlabs.ibm.com>
Am 07.11.2016 um 05:11 schrieb Paul Mackerras:
>> - Storing only the actually viewed diff. It's an interactive tool, so there's no advantage in displaying the diff in 0.001 seconds over viewing it in 0.1 seconds. As far as I can see, Gitk currently stores every diff it gets a hold of forever.
> It does?  That would be a bug. :)
> 
So far I've found three arrays being populated lazily (which is good) but never being released (which ignores changes to the underlying repo):
$commitinfo: one entry of about 500 bytes per line viewed in the list of commits. Maximum size of the array is the number of commits. As far as I can see, this array should be removed on a reload (Shift-F5).
$blobdifffd: one entry of about 45 bytes for every commit ever read. The underlying file descriptor gets closed, but the entry in this array remains. So far I didn't find the reason why this array exists at all. It's also not removed on a reload.
$treediffs: always the same number of entries as $blobdiffd, but > 1000 bytes/entry. Removed/refreshed on a reload (good!), different number of entries from that point on.
In case you want to play as well, here's the code I wrote for the investigation, it can be appended right at the bottom of the gitk script:
--------------8<---------------
proc variableSizes {} {
    # Add variable here to get them shown.
    global diffcontext diffids blobdifffd currdiffsubmod commitinfo
    global diffnexthead diffnextnote difffilestart
    global diffinhdr treediffs
    puts "---------------------------------------------------"
    foreach V [info vars] {
	if { ! [info exists $V] } {
	    continue
	}
	set count 0
	set bytes 0
	if [array exists $V] {
	    set count [array size $V]
	    foreach I [array get $V] {
		set bytes [expr $bytes + [string bytelength $I]]
	    }
	} elseif [catch {llength [set $V]}] {
	    set count [llength [set $V]]
#	    set bytes [string bytelength [list {*}[set $V]]]
	} else {
	    set bytes [string bytelength [set $V]]
	}
	puts [format "%20s: %5d items, %10d bytes" $V $count $bytes]
    }

# catch { # set output [memory info] # puts $output # }

    after 3000 variableSizes
}

variableSizes -------------->8---------------

[memory info] requires a Tcl with memory debug enabled.
Markus
-- 
- - - - - - - - - - - - - - - - - - -
Dipl. Ing. (FH) Markus Hitter
http://www.jump-ing.de/
Previous: Paul Mackerras
Message 7 of 7 in “gitk: avoid obscene memory consumption”
  1. Markus HitterNov 4, 2016
  2. Stefan BellerNov 4, 2016
  3. Paul MackerrasNov 5, 2016
  4. Markus HitterNov 6, 2016
  5. Jacob KellerNov 6, 2016
  6. Paul MackerrasNov 7, 2016
  7. Markus HitterNov 7, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.