Gradle 维护一个虚拟文件系统 (VFS),用于计算项目重复构建时需要重新构建的内容。通过监控文件系统,Gradle 可以在构建之间保持 VFS 的最新状态。

启用

自 Gradle 7 起,Gradle 默认针对受支持的操作系统启用文件系统监控。

运行构建时使用 '--watch-fs' 标志可强制对构建进行文件系统监控。

要强制对所有构建进行文件系统监控(除非使用 --no-watch-fs 禁用),请将以下值添加到 gradle.properties

org.gradle.vfs.watch=true

禁用

要禁用文件系统监控

  • 使用 --no-watch-fs 标志

  • gradle.properties 中设置 org.gradle.vfs.watch=false

排除文件和目录

Gradle 会自动从文件系统监控中排除一些常见目录(如 .git.gradlebuild/)。

目前没有公开机制来配置额外的文件系统监控排除项。

为了减少不必要的监控和重新执行,请考虑使用 fileTree.exclude() 限制特定任务的输入。

支持的操作系统

Gradle 使用原生操作系统特性来监控文件系统。Gradle 支持在以下操作系统上进行文件系统监控

  • Windows 10,版本 1709 及更高版本

  • Linux,已在以下发行版上测试

    • Ubuntu 16.04

    • CentOS Stream 9

    • Red Hat Enterprise Linux (RHEL) 8

    • Amazon Linux 2

    • Alpine Linux 3.20

  • macOS 12 (Monterey) 或更高版本,支持 Intel 和 ARM 架构

支持的文件系统

文件系统监控支持以下文件系统类型

  • APFS

  • btrfs

  • ext3

  • ext4

  • XFS

  • HFS+

  • NTFS

Gradle 还支持 VirtualBox 的共享文件夹。

不支持 Samba 和 NFS 等网络文件系统。也不支持 Microsoft Dev Drives (ReFS)。

不支持的文件系统

当默认启用时,文件系统监控在遇到不支持的文件系统上的内容时会采取保守措施。如果从网络驱动器挂载项目目录或子目录,可能会发生这种情况。当默认启用时,Gradle 在构建之间不会保留有关不支持文件系统的信息。如果显式启用文件系统监控,Gradle 将在构建之间保留有关不支持文件系统的信息。

通过符号链接访问的项目中的文件和目录无法从文件系统监控优化中受益。

日志记录

要查看构建开始和结束时虚拟文件系统 (VFS) 更改的信息,请启用详细的 VFS 日志记录。

org.gradle.vfs.verbose Daemon 选项设置为 true 以启用详细日志记录。

您可以使用以下命令在命令行上执行此操作

$ gradle <task> -Dorg.gradle.vfs.verbose=true

或者在项目根目录或您的 Gradle 用户主目录中的 gradle.properties 文件中配置该属性

org.gradle.vfs.verbose=true

这将在构建开始和结束时产生以下输出

$ ./gradlew assemble --watch-fs -Dorg.gradle.vfs.verbose=true
Received 3 file system events since last build while watching 1 locations
Virtual file system retained information about 2 files, 2 directories and 0 missing files since last build
> Task :compileJava NO-SOURCE
> Task :processResources NO-SOURCE
> Task :classes UP-TO-DATE
> Task :jar UP-TO-DATE
> Task :assemble UP-TO-DATE

BUILD SUCCESSFUL in 58ms
1 actionable task: 1 up-to-date
Received 5 file system events during the current build while watching 1 locations
Virtual file system retains information about 3 files, 2 directories and 2 missing files until next build

在 Windows 和 macOS 上,Gradle 可能会报告自上次构建以来收到的更改,即使您没有更改任何内容。这些是关于 Gradle 缓存更改的无害通知,可以安全地忽略。

故障排除

Gradle 未检测到某些更改

在 Gradle 社区 Slack 上告知我们如果构建正确声明了其输入和输出,则不应发生这种情况。因此,这要么是我们必须修复的错误,要么您的构建缺少某些输入或输出的声明。

由于状态丢失导致 VFS 状态丢弃

您在构建过程中是否收到一条消息,内容为 Dropped VFS state due to lost state在 Gradle 社区 Slack 上告知我们这意味着您的构建由于以下原因之一无法从文件系统监控中受益

  • Daemon 收到未知的文件系统事件

  • 发生了太多更改,监控 API 无法处理

macOS 上打开的文件过多

如果您在 macOS 上收到 java.io.IOException: Too many open files 错误,请提高您的打开文件限制。有关更多详细信息,请参阅此帖子

调整 Linux 上的 inotify 监控限制

文件系统监控在 Linux 上使用 inotify。根据您的构建大小,可能需要增加 inotify 限制。如果您正在使用 IDE,那么您过去可能已经不得不增加限制。

文件系统监控对每个监控目录使用一个 inotify 监控。您可以通过运行以下命令查看每个用户的 inotify 监控当前限制

cat /proc/sys/fs/inotify/max_user_watches

要将限制增加到例如 512K 监控,请运行以下命令

echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
sudo sysctl -p --system

每个使用的 inotify 监控占用最多 1KB 内存。假设 inotify 使用所有 512K 监控,那么文件系统监控最多可以使用 500MB。在内存受限的环境中,您可能需要禁用文件系统监控。

检查 Linux 上的 inotify 实例限制

文件系统监控为每个守护进程初始化一个 inotify 实例。您可以通过运行以下命令查看每个用户的 inotify 实例当前限制

cat /proc/sys/fs/inotify/max_user_instances

默认的每个用户实例限制应该足够高,因此我们不建议手动增加该值。