有没有办法限制“git gc”使用的内存量?

时间:2010-06-22 17:58:15

标签: git memory dreamhost git-gc

我正在共享主机上托管git repo。我的repo必然有几个非常大的文件,每次我尝试在repo上运行“git gc”时,我的进程被共享主机提供程序杀死,因为使用了太多内存。有没有办法限制git gc可以消耗的内存量?我希望它能够以更快的速度交换内存使用,并且需要更长的时间来完成它的工作。

5 个答案:

答案 0 :(得分:33)

我使用了此link的说明。与Charles Baileys建议的想法相同。

命令的副本在这里:

git config --global pack.windowMemory "100m"
git config --global pack.packSizeLimit "100m"
git config --global pack.threads "1"

这对我在hostgator上使用共享主机帐户。

答案 1 :(得分:15)

是的,请查看git config的帮助页面并查看pack.*选项,特别是pack.depthpack.windowpack.windowMemory和{{ 1}}。

这不是一个完全确切的大小,因为git需要将每个对象映射到内存中,因此无论窗口和增量缓存设置如何,一个非常大的对象都会导致大量内存使用。

您可以更好地在本地打包并“手动”将包文件传输到远程端,添加pack.deltaCacheSize个文件,以便远程git不会尝试完全重新包装所有内容。

答案 2 :(得分:10)

Git repack的内存使用是:(pack.deltaCacheSize + pack.windowMemory) × pack.threads。相应的默认值为256MiB,无限制,nproc。

delta缓存没用:大部分时间都花在计算滑动窗口的增量上,其中大部分被丢弃;缓存幸存者,这样他们可以重复使用一次(写作时)不会改善运行时。线程之间也不共享该缓存。

默认情况下,窗口内存限制为pack.windowgc.aggressiveWindow)。以这种方式限制包装是一个坏主意,因为工作集的大小和效率会有很大差异。最好将两者都提高到更高的值,并依靠pack.windowMemory来限制窗口大小。

最后,线程的缺点是拆分工作集。降低pack.threads并增加pack.windowMemory以使总数保持不变可以改善运行时间。

repack还有其他有用的可调参数(pack.depthpack.compression,位图选项),但它们不会影响内存使用。

答案 3 :(得分:7)

您可以使用关闭delta属性来仅为这些路径名的blob禁用delta压缩:

foo/.git/info/attributes(或foo.git/info/attributes,如果它是裸存储库)(请参阅gitattributes中的增量条目,并参见gitignore了解模式语法):

/large_file_dir/* -delta
*.psd -delta
/data/*.iso -delta
/some/big/file -delta
another/file/that/is/large -delta

这不会影响存储库的克隆。要影响其他存储库(即克隆),请将属性放在.gitattributes文件中,而不是info/attributes文件中(或除此之外)。

答案 4 :(得分:1)

Git 2.18(2018年第二季度)将改善gc内存消耗 在2.18之前,“git pack-objects”需要在执行其工作时分配大量“struct object_entry”:缩小其大小有助于提高性能 相当多 这会影响git gc

请参阅commit f6a5576commit 3b13a5fcommit 0aca34ecommit ac77d0ccommit 27a7d06commit 660b373commit 0cb3c14,{{3} },commit 898eba5commit 43fa44fcommit 06af3bbcommit b5c0cbdcommit 0c6804acommit fd9b1bacommit 8d6ccce(2018年4月14日){ {3}}。
(由commit 4c2db93合并于Nguyễn Thái Ngọc Duy (pclouds),2018年5月23日)

  

pack-objects:重新排序成员以缩小struct object_entry

     

以前的补丁会在此结构中留下大量漏洞和填充   此修补程序重新排序成员并将结构缩小到80个字节   (在64位系统上从136字节开始,在完成任何字段缩小之前)   有16位备用(和in_pack_header_size时多一些)   我们真的没用了。)

     

这是一系列内存减少补丁中的最后一个(参见   “Junio C Hamano -- gitster --”   第一个)。

     

总的来说,他们减少了linux-2.6.git上的重新包装内存大小   3.747G至3.424G,或约320M,减少8.5%   重新包装的运行时间在整个系列中保持不变   Ævar对他可以访问的大型monorepo(大于linux-2.6.git)的测试显示减少了7.9%,因此整体预期的改进应该是   大约8%左右。

使用Git 2.20(Q8 2018),可以更容易地检查一个fork中存在的对象是否与另一个未出现在同一分叉存储库中的对象形成delta。

commit ad635e8pack-objects: a bit of document about struct object_entrycommit fe0ac2fcommit 108f530(2018年8月16日)。 帮助:commit f64ba53Christian Couder (chriscool) Jeff King (peff)Duy Nguyen (pclouds)commit 9eb0986commit 16d75facommit 28b8a73(2018年8月16日)。 帮助:commit c8d521fJeff King (peff) (由Jeff King (peff)合并于Duy Nguyen (pclouds),2018年9月17日)

  

pack-objects:将“layer”移动到“struct packing_data

     

这会将'struct object_entry'的大小从88个字节减少到80个,从而使打包对象更有效。

     

例如,在具有12M对象的Linux存储库上,即使未使用图层功能,git pack-objects --all也需要额外的96MB内存。

请注意,Git 2.21(2019年2月)修复了一个小错误:“git pack-objects”错误地使用了未初始化的互斥锁,该错误已被更正。

Junio C Hamano -- gitster --commit f3504eacommit edb673c(2019年1月25日) 帮助:commit 459307b
Patrick Hogg (``)合并于Junio C Hamano (gitster),2019年2月5日)

  

pack-objects:将read mutex移动到packing_data struct

     

Junio C Hamano -- gitster --(“pack-objects:缩小结构object_entry中的尺寸字段”,   2018-04-14)新增了read_lock / read_unlock的额外用法   为并行调用中的线程安全性引入了oe_get_size_slow   try_delta()
  不幸的是oe_get_size_slow也用于串行   代码,其中一些在第一次调用之前被调用   ll_find_deltas
  因此,不保证读取互斥锁被初始化。

     

通过将读取的互斥锁移动到packing_data并初始化来解决此问题   它在prepare_packing_data中,它在cmd_pack_objects初始化。

Git 2.21(2019年2月)仍然找到另一种方法,用“git pack-objects”学习另一种算法来计算包的大小 要发送的对象,将生成的packfile交换为保存 横向成本支持小推动。

  

pack-objects:创建pack.useSparse设置

     

--sparse”中的“git pack-objects”标志会更改算法   用于枚举对象更快的个人对象   用户推送只改变小锥体的新对象   工作目录   建议不要为服务器使用稀疏算法,因为服务器可能会发送出现在整个工作目录中的新对象。

     

创建一个启用此新算法的“pack.useSparse”设置   这允许'git push'使用此算法而不传递   '--sparse'一直标记run_command()的四个级别   调用

     

如果设置了“--no-sparse”标志,则此配置设置为   重写的。

commit d243a32现在包括:

pack.useSparse:
     

如果为true,Git将默认使用“--sparse”选项       当“git pack-objects”选项存在时,“--revs”       这个       算法仅处理出现在引入新路径的路径中的树       对象。

     

这可以带来显着的性能优势       计算一个包发送一个小的变化。

     

然而,这是可能的       如果包含,则将额外的对象添加到包文件中   提交包含某些类型的直接重命名。

有关具体说明,请参阅“ac77d0c”。