Skip to content

Commit

Permalink
Correct pack memory leak causing git gc to try to exceed ulimit
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Shawn O. Pearce authored and Junio C Hamano committed Jul 9, 2008
1 parent e09c4e7 commit eac12e2
Showing 1 changed file with 1 addition and 0 deletions.
1 change: 1 addition & 0 deletions sha1_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit eac12e2

Please sign in to comment.