.gradle
文件夹)显示许多依赖项以相同的版本多次出现:1x在jars-9
和1x在modules-2
中:
为什么会发生这种情况,如何避免?由于此原因,我们的CI缓存比实际需要的大20-30%,尤其是对于像Kotlin编译器这样的大型依赖项:
JAR之间的大小差异可以归因于JAR文件压缩开启或关闭,它们在内容上是相同的。
官方解释关于.gradle
文件夹结构的说明并没有帮助。
.gradle
文件夹)显示许多依赖项以相同的版本多次出现:1x在jars-9
和1x在modules-2
中:
为什么会发生这种情况,如何避免?由于此原因,我们的CI缓存比实际需要的大20-30%,尤其是对于像Kotlin编译器这样的大型依赖项:
JAR之间的大小差异可以归因于JAR文件压缩开启或关闭,它们在内容上是相同的。
官方解释关于.gradle
文件夹结构的说明并没有帮助。
Gradle的依赖缓存旨在提高效率和可靠性。 它包括两种主要的存储类型:
基于文件的下载工件存储,包括二进制文件(如jar文件)和原始下载元数据(如POM和Ivy文件)。 下载工件的存储路径包括SHA1校验和,这意味着具有相同名称但内容不同的两个工件可以轻松缓存($GRADLE_USER_HOME/caches
)。
已解析的模块元数据的二进制存储,包括解析动态版本、模块描述符和工件的结果。
你在Gradle缓存中看到的jars-*
和modules-2
目录与这两种不同类型的存储相关。
jars-*
目录可能是指基于文件的下载工件存储。 存储在此目录中的每个工件在其存储路径中都包括SHA1校验和。 这种设计允许Gradle缓存具有相同名称但内容不同的两个工件,并确保如果具有相同SHA1校验和的工件已经存在于缓存中,则不会多次下载相同的工件。
modules-2
目录则是指已解析模块元数据的二进制存储区。该目录以二进制格式保存了依赖项解析的各个方面的记录,包括将动态版本解析为具体版本的结果、特定模块的已解析模块元数据以及特定构件的已解析构件元数据。
这两个目录之间是不同的,因为它们提供了不同的功能并存储不同类型的数据。
当Gradle解析依赖项时,它会下载依赖项的JAR文件并将其存储在
modules-2
目录中。如果对依赖项应用类路径转换,则转换的结果(如果使用身份转换,则可能与原始结果相同)会存储在
jars-*
目录中。这使得Gradle可以缓存转换的结果,避免将来使用相同的转换和相同的依赖项时再次执行转换。这就解释了为什么内容完全相同。
在减小CI缓存大小方面,由于Gradle缓存的工作方式,不同缓存目录中相同依赖项的多个实例可能是无法避免的。
但是,您可以配置CI/CD管道以仅缓存必要的目录或文件,或使用增量构建等技术来最小化需要缓存的数据量。
您还可以考虑定期手动或编程方式清理Gradle缓存,以删除未使用或过时的文件。
module-2
中的文件与下载的完全一样,而在jars-9
中则是未压缩的重复存储,这样可以更快地访问其内容,因为您无需解压它。只是一个大胆的猜测。 - Vampirejars-9
包含了类路径转换的结果。例如,用于检测配置缓存输入的仪器化。也有一些情况下会进行身份转换,但我没有进一步研究为什么会这样,以及是否有任何意义。 - Vampire