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 上告知我们。 如果构建正确声明了其输入和输出,则不应发生这种情况。因此,这要么是我们需要修复的 bug,要么是您的构建缺少对某些输入或输出的声明。

由于状态丢失而丢弃 VFS 状态

您在构建期间是否收到了显示 Dropped VFS state due to lost state 的消息? 请在 Gradle 社区 Slack 上告知我们。 这意味着您的构建由于以下原因之一无法受益于文件系统监视

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

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

macOS 上打开文件过多

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

调整 Linux 上的 inotify watches 限制

文件系统监视在 Linux 上使用 inotify。根据构建的大小,可能需要提高 inotify 限制。如果您正在使用 IDE,那么您过去可能已经需要提高这些限制了。

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

cat /proc/sys/fs/inotify/max_user_watches

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

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

每个使用的 inotify watch 占用最多 1KB 内存。假设 inotify 使用了所有 512K watches,那么文件系统监视可能会占用高达 500MB 内存。在内存受限的环境中,您可能希望禁用文件系统监视。

检查 Linux 上的 inotify instances 限制

文件系统监视为每个 daemon 初始化一个 inotify instance。您可以通过运行以下命令查看每个用户的 inotify instances 当前限制

cat /proc/sys/fs/inotify/max_user_instances

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