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

问题描述 投票:29回答:5

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

git memory dreamhost git-gc
5个回答
15
投票

是的,看看git config的帮助页面,看看pack.*选项,特别是pack.depthpack.windowpack.windowMemorypack.deltaCacheSize

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

你可能有更好的运气包装本地和“手动”将包文件传输到远程端,添加一个qazxsw poi文件,以便远程git不会尝试完全重新包装一切。


34
投票

我使用了这个.keep的指令。与link建议的想法相同。

命令的副本在这里:

Charles Baileys

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


10
投票

Git repack的内存使用是:git config --global pack.windowMemory "100m" git config --global pack.packSizeLimit "100m" git config --global pack.threads "1" 。相应的默认值为256MiB,无限制,nproc。

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

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

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

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


7
投票

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

pack.compression(或foo/.git/info/attributes,如果它是一个裸存储库)(请参阅foo.git/info/attributes中的delta条目并查看gitattributes的模式语法):

gitignore

这不会影响存储库的克隆。要影响其他存储库(即克隆),请将属性放在/large_file_dir/* -delta *.psd -delta /data/*.iso -delta /some/big/file -delta another/file/that/is/large -delta 文件中,而不是(或除了).gitattributes文件之外。


1
投票

Git 2.18(2018年第二季度)将改善gc内存消耗。 在2.18之前,“info/attributes”需要在完成工作时分配大量的“git pack-objects”:缩小它的尺寸有助于提高性能。 这会影响struct object_entry

参见git gccommit f6a5576commit 3b13a5fcommit 0aca34ecommit ac77d0ccommit 27a7d06commit 660b373commit 0cb3c14commit 898eba5commit 43fa44fcommit 06af3bbcommit b5c0cbdcommit 0c6804acommit fd9b1bacommit 8d6cccecommit 4c2db93(2018年4月14日)。 (由Nguyễn Thái Ngọc Duy (pclouds)合并于Junio C Hamano -- gitster --,2018年5月23日)

commit ad635e8:重新排序成员以缩小pack-objects

以前的补丁在这个结构中留下了很多洞和填充。 这个补丁重新排序成员并将结构缩小到80字节(从64位系统上的136个字节开始,在完成任何字段收缩之前),备用16位(当我们真正耗尽位时,在in_pack_header_size中还有几个) 。

这是一系列内存减少补丁中的最后一个(参见第一篇的“struct object_entry”)。

总体而言,他们将pack-objects: a bit of document about struct object_entry的重新包装内存大小从3.747G减少到3.424G,或减少了大约320M,减少了8.5%。 重新包装的运行时间在整个系列中保持不变。 Ævar对他可以获得的大型monorepo(大于linux-2.6.git)的测试显示减少了7.9%,因此整体预期的改善应该在8%左右。


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

参见linux-2.6.gitcommit fe0ac2fcommit 108f530commit f64ba53(2018年8月16日)。 帮助:Christian Couder (chriscool)Jeff King (peff)。 参见Duy Nguyen (pclouds)commit 9eb0986commit 16d75facommit 28b8a73commit c8d521f(2018年8月16日)。 帮助:Jeff King (peff)Jeff King (peff)。 (由Duy Nguyen (pclouds)合并于Junio C Hamano -- gitster --,2018年9月17日)

commit f3504ea:将'pack-objects'移动到'layer'

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

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


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

参见git pack-objects --allcommit edb673ccommit 459307b(2019年1月25日)。 帮助:Patrick Hogg (``)。 (由Junio C Hamano (gitster)合并于Junio C Hamano -- gitster --,2019年2月5日)

commit d243a32:将read mutex移动到pack-objects struct

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

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


Git 2.21(2019年2月)仍然找到另一种方法来缩小包的大小,用“cmd_pack_objects”学习另一种算法来计算要发送的对象集,将生成的包文件交换掉以节省遍历成本以支持小推送。

git pack-objects:创建pack-objects设置

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

创建一个启用此新算法的'git pack-objects'设置。 这允许'pack.useSparse'使用这个算法而不会通过'git push'标志一直通过四个级别的--sparse调用。

如果设置了'run_command()'标志,则覆盖此配置设置。

--no-sparse现在包括:

config pack documentation

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

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.