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

sam*_*max 32 memory git dreamhost git-gc

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

小智 34

我使用了这个链接的说明.与Charles Baileys建议的想法相同.

命令的副本在这里:

git config --global pack.windowMemory "100m"
git config --global pack.packSizeLimit "100m"
git config --global pack.threads "1"
Run Code Online (Sandbox Code Playgroud)

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

  • 谢谢!这对我有用,但我认为第二行有一个拼写错误 - 没有SizeLimit选项; 它应该是:git config --global pack.packSizeLimit"100m" (2认同)

CB *_*ley 15

是的,看看您的帮助页面git config,并期待在pack.*选择,特别是pack.depth,pack.window,pack.windowMemorypack.deltaCacheSize.

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

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


Tob*_*obu 11

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

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

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

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

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


Chr*_*sen 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
Run Code Online (Sandbox Code Playgroud)

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


Von*_*onC 7

Git 2.18(2018 年第二季度)将改善 gc 内存消耗。
\n在 2.18 之前,“ ”在工作时git pack-objects需要分配大量的“ ”:缩小其大小对性能有很大帮助。\n这会影响.struct object_entry
git gc

\n

请参阅提交 f6a5576提交 3b13a5f、提交0aca34e、提交ac77d0c、提交27a7d06提交 660b373提交 0cb3c14、提交 898eba5 、提交 43fa44f 提交06af3bb提交 b5c0cbd提交 0c6804a提交 fd9b1ba提交 8d6ccce提交 4c2db93(2018 年 4 月 14 日)由Nguy\xe1\xbb\x85n Th\xc3\xa1i Ng\xe1\xbb\x8dc Duy ( )。\n (由Junio C Hamano 合并 -- --提交 ad635e8中,2018 年 5 月 23 日)pclouds
gitster

\n
\n

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

\n
\n
\n

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

\n

这是一系列内存减少补丁中的最后一个(请参阅\n“ pack-objects:关于 struct object_entry 的一些文档第一个

\n

总体而言,他们将重新打包内存大小linux-2.6.git从 3.747G 减少到 3.424G,即减少了约 320M,减少了 8.5%。
\n重新打包的运行时间在整个系列中保持不变。
\n\xc3\x86var\ 在他有权访问的大型 monorepo 上进行测试(大于linux-2.6.git)上进行的测试显示减少了 7.9%,因此总体预期改进应该在 8% 左右。

\n
\n
\n

使用 Git 2.20(2018 年第 4 季度),可以更轻松地检查一个分叉中存在的对象是否与未出现在同一分叉存储库中的另一个对象形成增量。

\n

请参阅Christian Couder ( )的提交 fe0ac2f提交 108f530提交 f64ba53(2018 年 8 月 16 日)。\n帮助者:Jeff King ( )Duy Nguyen ( )。\n请参阅Jeff King的提交 9eb0986提交 16d75fa提交 28b8a73提交 c8d521f(2018 年 8 月 16 日。\n帮助者:Jeff King ( )Duy Nguyen ( )。\n (由Junio C Hamano 合并 -- --提交 f3504ea中,2018 年 9 月 17 日)chriscool
peffpclouds
peff
peffpclouds
gitster

\n
\n

pack-objects: 搬进 \' layer\ struct packing_data'

\n
\n
\n

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

\n

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

\n
\n
\n

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

\n

请参阅提交 edb673c提交 459307b(2019 年 1 月 25 日),作者:Patrick Hogg (``)
\n帮助者:Junio C Hamano ( gitster)
\n (由Junio C Hamano 合并 -- gitster--提交 d243a32中,2019 年 2 月 5 日)

\n
\n

pack-objects:将读取互斥体移动到packing_data结构体

\n
\n
\n

ac77d0c (" pack-objects: 结构体中的收缩大小字段object_entry",\n2018-04-14) 在新引入的 read_lock/read_unlock 中添加了额外的用法,oe_get_size_slow以保证并行调用中的线程安全try_delta()
\n不幸的是oe_get_size_slow,它也在串行代码中使用,其中一些代码在第一次调用之前被调用。\n ll_find_deltas
\n因此,不保证读取互斥体被初始化。

\n

通过将读取互斥体移至packing_data并在prepare_packing_data 中初始化\nit 来解决此问题,该数据在中初始化cmd_pack_objects来解决此问题。

\n
\n
\n

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

\n
\n

pack-objects: 创造pack.useSparse设置

\n
\n
\n

\' --sparse\' 中的 \' git pack-objects\' 标志将用于枚举对象的算法\n更改为对于单个用户推送仅更改工作目录的一小部分\n的新对象\n来说速度更快的算法。
\n不建议对服务器使用稀疏算法,因为服务器可能会发送出现在整个工作目录中的新对象。

\n

创建pack.useSparse启用此新算法的“\”设置。
\n这允许 \' git push\' 使用此算法,而无需--sparse在四个级别的调用中一直传递 \n\' \' 标志run_command()

\n

如果--no-sparse设置了“\”标志,则此配置设置将被覆盖。

\n
\n

配置包文档现在包括:

\n
\n
pack.useSparse:\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

当计算一个包来发送小额零钱时,这可以带来显着的性能优势。

\n

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

\n
\n

具体说明请参见“git push对于一个巨大的存储库来说非常慢”。

\n
\n

注意:正如 Git 2.24 中所评论的,类似的设置pack.useSparse仍处于实验阶段。

\n

请参阅提交 aaf633c提交 c6cc4c5提交 ad0fb65提交 31b1de6提交 b068d9a提交 7211b9e(2019 年 8 月 13 日),作者:Derrick Stolee ( derrickstolee)
\n (由Junio C Hamano 合并 -- gitster--提交 f4f8dfe,2019 年 9 月 9 日)

\n
\n

repo-settings:创建feature.experimental设置

\n
\n
\n

\' feature.experimental\' 设置包括未承诺成为默认值的配置选项,但可以使用额外的测试

\n

更新以下配置设置以采用新的默认值,并\n使用该repo_settings结构(如果尚未使用它们):

\n
    \n
  • \'pack.useSparse=true\'
  • \n
  • \'fetch.negotiationAlgorithm=跳过\'
  • \n
\n
\n
\n

在 Git 2.26(2020 年第一季度)中,“”重用现有包中存储的对象来生成其结果的方式git pack-objects得到了改进。

\n

请参阅提交 d2ea031提交 92fb0db提交 bb514de 、提交 ff48302 、提交e704fc7 提交2f4af77提交 8ebf529提交 59b2829、提交 40d18ff 、提交 14fbd26 2019 年 12 月 18 日)和提交 56d9cbe、提交bab28d9(2019 年 9 月 13 日)作者:Jeff King ( )。\n (由Junio C Hamano 合并 -- --提交 a14aebe中,2020 年 2 月 14 日)peff
gitster

\n
\n

pack-objects:改进部分包文件重用

\n

帮助者:Jonathan Tan
\n签字人:Jeff King
\n签字人:Christian Couder

\n
\n
\n

重用现有包文件中的增量的旧代码只是尝试逐字转储包的整个片段。这比实际将对象添加到装箱单的传统方法更快,但它并不经常起作用。这个新代码实际上是在寻求中间立场:做一些针对每个对象的工作,但比我们传统上做的要少得多。

\n

新代码的一般策略是从我们将包含的包文件中创建对象的位图,然后对其进行迭代,完全按照磁盘包中的方式写出每个对象,但不将其添加到我们的包中packlist(这会消耗内存,并增加增量的搜索空间)。

\n

一个复杂的问题是,如果我们省略了一些对象,我们就无法针对我们不发送的基础设置增量。所以我们必须检查每个对象try_partial_reuse()以确保我们有它的增量。

\n

关于性能,在最坏的情况下,我们可能会交错发送或不发送的对象,并且我们将拥有与对象一样多的块。但实际上我们会发送大块。

\n

例如,在 GitHub 服务器上打包 torvalds/linux 现在重用了 650 万个对象,但只需要约 50k 块。

\n
\n
\n

使用 Git 2.34(2021 年第 4 季度),git repack其本身(由git gc)受益于内存使用量的减少。

\n

请参阅提交 b017334提交 a9fd2f2提交 a241878(2021 年 8 月 29 日),作者:Taylor Blau ( ttaylorr)
\n (由Junio C Hamano 合并 -- gitster--提交 9559de3中,2021 年 9 月 10 日)

\n
\n

builtin/pack-objects.c:删除重复的哈希查找

\n

签署人:泰勒·布劳 (Taylor Blau)

\n
\n
\n

在08cdfb1的原始代码(“pack-objects --keep-unreachable”,2007-09-16,Git v1.5.4-rc0 -- merge, )中,我们将每个对象添加到类型为 ``obj->type where objcomes from的打包列表中lookup_unknown_object()
\n除非我们已经查找并解析了该对象,否则这将是OBJ_NONE.
\n那很好,因为将位oe_set_type()设置type_valid为“0”,我们稍后确定真实类型。

\n

因此,我们在对象查找中唯一需要的是访问该flags字段,以便我们可以标记我们已添加该对象,OBJECT_ADDED以避免再次添加它(我们可以OBJ_NONE直接传递,而不是从对象中抓取它)。

\n

add_object_entry()已经拒绝重复!这是自7a979d9以来的行为(“Thin pack - 创建缺少 delta 基数的 packfile。”,2006-02-19,Git v1.3.0-rc1 - merge),但08cdfb1没有利用它。
\n此外,为了进行OBJECT_ADDED检查,我们必须在obj_hash.

\n

因此,我们可以lookup_unknown_object()完全放弃呼叫,也放弃标志OBJECT_ADDED,因为我们在这里接触的点是唯一检查它的位置。

\n

最后,我们执行相同数量的哈希查找,但还有一个额外的好处,那就是我们不会浪费内存分配对象OBJ_NONE(如果我们正在遍历,我们最终会需要它,但是这段代码的全部要点路径不是要遍历的)。

\n
\n
\n

Git 2.36(2022 年第 2 季度)已更正配置变量fetch.negotiationAlgorithm之间的交互。feature.experimental

\n

请参阅Elijah Newren ( )的提交 714edc6提交 a9a136c提交 a68c5b9(2022 年 2 月 2 日)。\n (由Junio C Hamano 合并 --