Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce the number of ArchivePathTree instances for the same path and opening same JARs multiple times #35364

Merged
merged 1 commit into from
Aug 17, 2023

Conversation

aloubyansky
Copy link
Member

Related to #35280

This change reduces the number of ArchivePathTree instances (pretty much to 1 per JAR) and enables sharing of ZIP FS instances between Quarkus classloaders.

The new behavior is enabled by default but can be disabled by adding -Dbootstrap.quarkus.disable-jar-cache to the command line launching dev mode, for example.

With this change DevMojoIT#testThatTheApplicationIsReloadedMultiModule passes on my laptop with -Xmx95m instead of -Xmx115 running with -Dbootstrap.quarkus.disable-jar-cache.

@quarkus-bot quarkus-bot bot added area/core area/devtools Issues/PR related to maven, gradle, platform and cli tooling/plugins area/maven area/testing labels Aug 15, 2023
@aloubyansky aloubyansky requested a review from gsmet August 15, 2023 21:32
@quarkus-bot

This comment has been minimized.

@gsmet
Copy link
Member

gsmet commented Aug 16, 2023

I think I would refrain to backport to 3.2 for now but I will backport it to 3.3.

Copy link
Member

@gsmet gsmet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggested some minor improvements, let me know what you think.

@@ -47,7 +47,7 @@ static PathTree ofDirectoryOrArchive(Path p) {
static PathTree ofDirectoryOrArchive(Path p, PathFilter filter) {
try {
final BasicFileAttributes fileAttributes = Files.readAttributes(p, BasicFileAttributes.class);
return fileAttributes.isDirectory() ? new DirectoryPathTree(p, filter) : new ArchivePathTree(p, filter);
return fileAttributes.isDirectory() ? new DirectoryPathTree(p, filter) : SharedArchivePathTree.forPath(p, filter);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it make more sense to test if it is enabled here and fall back to standard ArchivePathTree if not?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps SharedArchivePathTree could be enhanced with a static boolean isEnabled() and then yes.

*/
static ArchivePathTree forPath(Path path) {
return ENABLE_SHARING
? cache.computeIfAbsent(path, k -> new SharedArchivePathTree(path))
Copy link
Member

@gsmet gsmet Aug 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think applying the following patch would avoid the lambdas:

diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/SharedArchivePathTree.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/SharedArchivePathTree.java
index 63c5a39b529..372dd1401d0 100644
--- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/SharedArchivePathTree.java
+++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/SharedArchivePathTree.java
@@ -40,9 +40,11 @@ class SharedArchivePathTree extends ArchivePathTree {
      * @return instance of {@link ArchivePathTree}, never null
      */
     static ArchivePathTree forPath(Path path) {
-        return ENABLE_SHARING
-                ? cache.computeIfAbsent(path, k -> new SharedArchivePathTree(path))
-                : new ArchivePathTree(path);
+        if (!ENABLE_SHARING) {
+            return new ArchivePathTree(path);
+        }
+
+        return cache.computeIfAbsent(path, SharedArchivePathTree::new);
     }
 
     /**
@@ -57,9 +59,11 @@ static ArchivePathTree forPath(Path path) {
      * @return instance of {@link ArchivePathTree}, never null
      */
     static ArchivePathTree forPath(Path path, PathFilter filter) {
-        return filter == null && ENABLE_SHARING
-                ? cache.computeIfAbsent(path, k -> new SharedArchivePathTree(path))
-                : new ArchivePathTree(path, filter);
+        if (filter != null) {
+            return new ArchivePathTree(path, filter);
+        }
+
+        return forPath(path);
     }
 
     /**
@@ -69,6 +73,10 @@ static ArchivePathTree forPath(Path path, PathFilter filter) {
      * @param path path to remove from the cache
      */
     static void removeFromCache(Path path) {
+        if (!ENABLE_SHARING) {
+            return;
+        }
+
         cache.remove(path);
     }
 

I can push to your branch if it makes sense to you.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll apply the changes now, thanks.

…opening same JARs multiple times

Co-authored by gsmet
Copy link
Member

@gsmet gsmet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice team work :).

I think we should refrain from backporting this tbh. And make sure we have it included in a CR before pushing it in a release.

Not having it is just some extra memory consumed and we have lived with it since forever.

@aloubyansky
Copy link
Member Author

Agreed

@yrodiere yrodiere added the triage/waiting-for-ci Ready to merge when CI successfully finishes label Aug 16, 2023
@quarkus-bot

This comment has been minimized.

@quarkus-bot
Copy link

quarkus-bot bot commented Aug 17, 2023

Failing Jobs - Building 240e0d9

Status Name Step Failures Logs Raw logs
JVM Tests - JDK 11 Build ⚠️ Check → Logs Raw logs
JVM Tests - JDK 17 Build Failures Logs Raw logs
✔️ JVM Tests - JDK 20

Failures

⚙️ JVM Tests - JDK 17 #

- Failing: integration-tests/hibernate-search-orm-elasticsearch-coordination-outbox-polling 

📦 integration-tests/hibernate-search-orm-elasticsearch-coordination-outbox-polling

Failed to execute goal org.codehaus.mojo:exec-maven-plugin:3.0.0:exec (docker-prune) on project quarkus-integration-test-hibernate-search-orm-elasticsearch-coordination-outbox-polling: Command execution failed.

@aloubyansky aloubyansky merged commit d30b3c4 into quarkusio:main Aug 17, 2023
@quarkus-bot quarkus-bot bot removed the triage/waiting-for-ci Ready to merge when CI successfully finishes label Aug 17, 2023
@quarkus-bot quarkus-bot bot added this to the 3.4 - main milestone Aug 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/core area/devtools Issues/PR related to maven, gradle, platform and cli tooling/plugins area/maven area/testing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants