Skip to content

Commit 60e48b1

Browse files
committed
Improve Maven cache architecture for better memory efficiency and performance
This comprehensive enhancement to Maven's caching system addresses memory issues and significantly improves performance through several key improvements: ## Key Features: - Enhanced DefaultRequestCache with configurable reference types and CSS-like selectors - Pluggable ModelObjectPool service architecture with configurable object types - Comprehensive cache statistics with eviction tracking - Improved InputLocation and InputSource with ImmutableCollections - Custom equality strategy for Dependency pooling - Enhanced parent request matching with interface checking - Configurable cache statistics display ## Performance Results: - Maven 3: Requires -Xmx1536m, runs in 45 seconds - Maven 4.0.0-rc-4: Runs with -Xmx1024m in 2'32" (cannot run with -Xmx512m) - Maven 4.0.0-rc-4 with -Xmx1536m: 2'5" - Maven 4.0.0-rc-4 + maven3Personality with -Xmx1536m: 1'14" - Maven 4 + this PR: Runs with -Xmx512m in 3'42" (more memory does not help) - Maven 4 + this PR + maven3Personality: Runs with -Xmx512m in 1'0" ## Memory Improvements: - Reduced minimum memory requirement from 1024m to 512m - Eliminated memory scaling issues - additional memory beyond 512m provides no benefit - Significant reduction in memory pressure through improved caching strategies This PR definitively solves memory problems while maintaining or improving performance.
1 parent 1a681ec commit 60e48b1

File tree

68 files changed

+5371
-934
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+5371
-934
lines changed

.github/release-drafter-3.x.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,3 @@
1616
# under the License.
1717

1818
_extends: maven-gh-actions-shared:.github/release-drafter.yml
19-
tag-template: maven-$RESOLVED_VERSION

.github/release-drafter.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
# under the License.
1717

1818
_extends: maven-gh-actions-shared
19-
tag-template: maven-$RESOLVED_VERSION
2019

2120
include-pre-releases: true
2221
prerelease: true

api/maven-api-core/src/main/java/org/apache/maven/api/Artifact.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
@Immutable
4040
public interface Artifact {
4141
/**
42-
* {@return a unique identifier for this artifact}.
42+
* {@return a unique identifier for this artifact}
4343
* The identifier is composed of groupId, artifactId, extension, classifier, and version.
4444
*
4545
* @see ArtifactCoordinates#getId()
@@ -58,23 +58,23 @@ default String key() {
5858
}
5959

6060
/**
61-
* {@return the group identifier of the artifact}.
61+
* {@return the group identifier of the artifact}
6262
*
6363
* @see ArtifactCoordinates#getGroupId()
6464
*/
6565
@Nonnull
6666
String getGroupId();
6767

6868
/**
69-
* {@return the identifier of the artifact}.
69+
* {@return the identifier of the artifact}
7070
*
7171
* @see ArtifactCoordinates#getArtifactId()
7272
*/
7373
@Nonnull
7474
String getArtifactId();
7575

7676
/**
77-
* {@return the version of the artifact}.
77+
* {@return the version of the artifact}
7878
* Contrarily to {@link ArtifactCoordinates},
7979
* each {@code Artifact} is associated to a specific version instead of a range of versions.
8080
* If the {@linkplain #getBaseVersion() base version} contains a meta-version such as {@code SNAPSHOT},
@@ -86,7 +86,7 @@ default String key() {
8686
Version getVersion();
8787

8888
/**
89-
* {@return the version or meta-version of the artifact}.
89+
* {@return the version or meta-version of the artifact}
9090
* A meta-version is a version suffixed with the {@code SNAPSHOT} keyword.
9191
* Meta-versions are represented in a base version by their symbols (e.g., {@code SNAPSHOT}),
9292
* while they are replaced by, for example, the actual timestamp in the {@linkplain #getVersion() version}.
@@ -122,7 +122,7 @@ default String key() {
122122
boolean isSnapshot();
123123

124124
/**
125-
* {@return coordinates with the same identifiers as this artifact}.
125+
* {@return coordinates with the same identifiers as this artifact}
126126
* This is a shortcut for {@code session.createArtifactCoordinates(artifact)}.
127127
*
128128
* @see org.apache.maven.api.Session#createArtifactCoordinates(Artifact)

api/maven-api-core/src/main/java/org/apache/maven/api/ArtifactCoordinates.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@
3333
@Immutable
3434
public interface ArtifactCoordinates {
3535
/**
36-
* {@return the group identifier of the artifact}.
36+
* {@return the group identifier of the artifact}
3737
*/
3838
@Nonnull
3939
String getGroupId();
4040

4141
/**
42-
* {@return the identifier of the artifact}.
42+
* {@return the identifier of the artifact}
4343
*/
4444
@Nonnull
4545
String getArtifactId();
@@ -53,7 +53,7 @@ public interface ArtifactCoordinates {
5353
String getClassifier();
5454

5555
/**
56-
* {@return the specific version, range of versions, or meta-version of the artifact}.
56+
* {@return the specific version, range of versions or meta-version of the artifact}
5757
* A meta-version is a version suffixed with the {@code SNAPSHOT} keyword.
5858
*/
5959
@Nonnull
@@ -69,7 +69,7 @@ public interface ArtifactCoordinates {
6969
String getExtension();
7070

7171
/**
72-
* {@return a unique string identifying this artifact}.
72+
* {@return a unique string representation identifying this artifact}
7373
*
7474
* The default implementation returns a colon-separated list of group
7575
* identifier, artifact identifier, extension, classifier and version.

api/maven-api-core/src/main/java/org/apache/maven/api/Constants.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,5 +622,66 @@ public final class Constants {
622622
*/
623623
public static final String MAVEN_LOGGER_LOG_PREFIX = MAVEN_LOGGER_PREFIX + "log.";
624624

625+
/**
626+
* User property key for cache configuration.
627+
*
628+
* @since 4.1.0
629+
*/
630+
public static final String MAVEN_CACHE_CONFIG_PROPERTY = "maven.cache.config";
631+
632+
/**
633+
* User property to enable cache statistics display at the end of the build.
634+
* When set to true, detailed cache statistics including hit/miss ratios,
635+
* request type breakdowns, and retention policy effectiveness will be displayed
636+
* when the build completes.
637+
*
638+
* @since 4.1.0
639+
*/
640+
@Config(type = "java.lang.Boolean", defaultValue = "false")
641+
public static final String MAVEN_CACHE_STATS = "maven.cache.stats";
642+
643+
/**
644+
* User property to configure separate reference types for cache keys and values.
645+
* Format: "key:value" where key and value can be NONE, SOFT, WEAK, or HARD.
646+
* Examples:
647+
* - "HARD:SOFT" - Keep keys strongly referenced, allow values to be garbage collected under memory pressure
648+
* - "WEAK:WEAK" - Allow both keys and values to be garbage collected aggressively
649+
* - "SOFT:HARD" - Allow keys to be GC'd under memory pressure, keep values strongly referenced
650+
*
651+
* This enables fine-grained analysis of cache misses caused by key vs value evictions.
652+
*
653+
* @since 4.1.0
654+
*/
655+
public static final String MAVEN_CACHE_KEY_VALUE_REFS = "maven.cache.keyValueRefs";
656+
657+
/**
658+
* User property key for configuring which object types are pooled by ModelObjectProcessor.
659+
* Value should be a comma-separated list of simple class names (e.g., "Dependency,Plugin,Build").
660+
* Default is "Dependency" for backward compatibility.
661+
*
662+
* @since 4.1.0
663+
*/
664+
@Config(defaultValue = "Dependency")
665+
public static final String MAVEN_MODEL_PROCESSOR_POOLED_TYPES = "maven.model.processor.pooledTypes";
666+
667+
/**
668+
* User property key for configuring the default reference type used by ModelObjectProcessor.
669+
* Valid values are: "SOFT", "HARD", "WEAK", "NONE".
670+
* Default is "HARD" for optimal performance.
671+
*
672+
* @since 4.1.0
673+
*/
674+
@Config(defaultValue = "HARD")
675+
public static final String MAVEN_MODEL_PROCESSOR_REFERENCE_TYPE = "maven.model.processor.referenceType";
676+
677+
/**
678+
* User property key prefix for configuring per-object-type reference types.
679+
* Format: maven.model.processor.referenceType.{ClassName} = {ReferenceType}
680+
* Example: maven.model.processor.referenceType.Dependency = SOFT
681+
*
682+
* @since 4.1.0
683+
*/
684+
public static final String MAVEN_MODEL_PROCESSOR_REFERENCE_TYPE_PREFIX = "maven.model.processor.referenceType.";
685+
625686
private Constants() {}
626687
}

api/maven-api-core/src/main/java/org/apache/maven/api/Dependency.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
@Immutable
3737
public interface Dependency extends Artifact {
3838
/**
39-
* {@return the type of the dependency}.
39+
* {@return the type of the dependency}
4040
* A dependency can be a <abbr>JAR</abbr> file,
4141
* a modular-<abbr>JAR</abbr> if it is intended to be placed on the module path,
4242
* a <abbr>JAR</abbr> containing test classes, <i>etc.</i>
@@ -47,7 +47,7 @@ public interface Dependency extends Artifact {
4747
Type getType();
4848

4949
/**
50-
* {@return the time at which the dependency will be used}.
50+
* {@return the time at which the dependency will be used}
5151
* It may be, for example, at compile time only, at run time or at test time.
5252
*
5353
* @see DependencyCoordinates#getScope()
@@ -66,7 +66,7 @@ public interface Dependency extends Artifact {
6666
boolean isOptional();
6767

6868
/**
69-
* {@return coordinates with the same identifiers as this dependency}.
69+
* {@return coordinates with the same identifiers as this dependency}
7070
*/
7171
@Nonnull
7272
@Override

api/maven-api-core/src/main/java/org/apache/maven/api/DownloadedArtifact.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
public interface DownloadedArtifact extends Artifact {
3434

3535
/**
36-
* {@return the a path to the file that has been downloaded to the file system}.
36+
* {@return the actual file that has been downloaded in the file system}
3737
*/
3838
Path getPath();
3939
}

api/maven-api-core/src/main/java/org/apache/maven/api/JavaPathType.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,8 @@ final String[] format(String moduleName, Iterable<? extends Path> paths) {
263263
if (option == null) {
264264
throw new IllegalStateException("No option is associated to this path type.");
265265
}
266-
String prefix = (moduleName == null) ? "\"" : (moduleName + "=\"");
267-
StringJoiner joiner = new StringJoiner(File.pathSeparator, prefix, "\"");
266+
String prefix = (moduleName == null) ? "" : (moduleName + '=');
267+
StringJoiner joiner = new StringJoiner(File.pathSeparator, prefix, "");
268268
joiner.setEmptyValue("");
269269
for (Path p : paths) {
270270
joiner.add(p.toString());

api/maven-api-core/src/main/java/org/apache/maven/api/SourceRoot.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,9 @@ default Path directory() {
6868
* If no syntax is specified, or if its length is 1 character (interpreted as a Windows drive),
6969
* the default is a Maven-specific variation of the {@code "glob"} pattern.
7070
*
71-
* <p>The default implementation returns an empty list, which means to apply a language-dependent pattern.
72-
* For example, for the Java language, the pattern includes all files with the {@code .java} suffix.</p>
71+
* <p>
72+
* The default implementation returns an empty list, which means to apply a language-dependent pattern.
73+
* For example, for the Java language, the pattern includes all files with the {@code .java} suffix.
7374
*
7475
* @see java.nio.file.FileSystem#getPathMatcher(String)
7576
*/

api/maven-api-core/src/test/java/org/apache/maven/api/JavaPathTypeTest.java

Lines changed: 0 additions & 68 deletions
This file was deleted.

0 commit comments

Comments
 (0)