Correct pack memory leak causing git gc to try to exceed ulimit
authorShawn O. Pearce <spearce@spearce.org>
Wed, 9 Jul 2008 07:10:07 +0000 (07:10 +0000)
committerJunio C Hamano <gitster@pobox.com>
Wed, 9 Jul 2008 21:45:42 +0000 (14:45 -0700)
When recursing to unpack a delta base we must unuse_pack() so that
the pack window for the current object does not remain pinned in
memory while the delta base is itself being unpacked and materialized
for our use.

On a long delta chain of 50 objects we may need to access 6 different
windows from a very large (>3G) pack file in order to obtain all
of the delta base content.  If the process ulimit permits us to
map/allocate only 1.5G we must release windows during this recursion
to ensure we stay within the ulimit and transition memory from pack
cache to standard malloc, or other mmap needs.

Inserting an unuse_pack() call prior to the recursion allows us to
avoid pinning the current window, making it available for garbage
collection if memory runs low.

This has been broken since at least before 1.5.1-rc1, and very
likely earlier than that.  Its fixed now.  :)

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
sha1_file.c

index d1c406081e29eab9843a5268b611af1a3e014227..10346b681e3575d17945f64513e2b0fecbcc01fc 100644 (file)
@@ -1609,6 +1609,7 @@ static void *unpack_delta_entry(struct packed_git *p,
        off_t base_offset;
 
        base_offset = get_delta_base(p, w_curs, &curpos, *type, obj_offset);
+       unuse_pack(w_curs);
        base = cache_or_unpack_entry(p, base_offset, &base_size, type, 0);
        if (!base)
                die("failed to read delta base object"