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
Immutable leak detection level #13459
base: 4.1
Are you sure you want to change the base?
Conversation
I've created a small benchmark to show the benefits (not transitive ones eg constant fold of decisions) of this at franz1981/java-puzzles@20a9ceb which got on
which show that the changes to allow a fast path on DISABLE always pay off but in the "stable" ie immutable level case it pays a lot. |
@@ -150,13 +158,19 @@ public static boolean isEnabled() { | |||
* Sets the resource leak detection level. | |||
*/ | |||
public static void setLevel(Level level) { | |||
if (stableLevel != null) { | |||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should better throw in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a stackless Unsupported Ex?
I'm saying that because maybe users don't want to have some special paths in their code able to set the level at runtime to handle the case when the level is "immutable"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure what is better... At least it wouldn't be surprising in a sense that while they think they use paranoid (for example) it not actually does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Me neither, be silent doesn't seem right, I agree...a warn?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have noticed https://github.com/eclipse-vertx/vert.x/blob/6a8aefb6ec84278774d2c03fdae83fdf1deafded/src/main/java/io/vertx/core/impl/VertxImpl.java#L104: it means that if I won't expose something public to check if the immutable sys prop is there, with an exception, this one will crash the application while starting
or...
I just add a warn?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any suggestion @normanmaurer ? do you want me to add an exception for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure ... @chrisvest @trustin thoughts ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking out loud, what about:
- Throwing an unsupported exception if the new level is different than the immutable one.
- Always require
io.netty.leakDetection.level
to be set when settingio.netty.immutableResourceLeakDetection
. This way we avoid the vert.x case.
buffer/src/main/java/io/netty/buffer/AbstractByteBufAllocator.java
Outdated
Show resolved
Hide resolved
Note on the DISABLE fast path: why don't let the JIT do it?
|
a9ba703
to
d30af65
Compare
Motivation: Unstrusted fields from the JDK perspective are more costy and subsequent decisions cannot be constant folded Modifications: Create a new sys property to set it up Result: Better performance and likely smaller native images for DISABLED cases
4b00b09
to
cd0f03b
Compare
@normanmaurer I've added a new hint This lead me to modify the default channel pipeline to do the same: instead of using an internal field |
Just wanted to add, that I've talked with Franz about how he can check what kind of effect this has on a GraalVM native-image for Quarkus - I do expect it to have some small effect since the Graal compiler will theoretically be able to do more folding of the static part of the class(es) (which we do enable in Quarkus) |
With the growing number of props, should we create a dedicated wiki page for props and their definition? |
@zakkak I would like your opinion on this, related potential improvements we could get on native image or if we have other options which doesn't require it |
|
||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(ResourceLeakDetector.class); | ||
|
||
static { | ||
final boolean immutableLevel = SystemPropertyUtil.get("io.netty.immutableResourceLeakDetection") != null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest changing the property name and explicitly treating it as a boolean:
final boolean immutableLevel = SystemPropertyUtil.get("io.netty.immutableResourceLeakDetection") != null; | |
final boolean immutableLevel = Boolean.getBoolean("io.netty.leakDetection.level.immutable"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but use SystemPropertyUtil.getBoolean()
instead of Boolean.getBoolean()
@@ -97,10 +97,12 @@ static Level parseLevel(String levelStr) { | |||
} | |||
|
|||
private static Level level; | |||
private static final Level stableLevel; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe call it immutableLevel
?
@@ -139,33 +147,43 @@ public static void setEnabled(boolean enabled) { | |||
setLevel(enabled? Level.SIMPLE : Level.DISABLED); | |||
} | |||
|
|||
private static boolean isImmutableDisabled() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be slightly better:
private static boolean isImmutableDisabled() { | |
private static boolean isImmutablyDisabled() { |
Currently Quarkus sets In theory (you could confirm it by setting app a small Quarkus test and observing the generated binary size, as well as the number of reachable classes/methods) this should suffice, and would give you the benefits you expect (i.e. the static analysis will understand that you are disabling the leak detection and throw away all relevant parts as dead code).
AFAIK this (i.e., guarding dead code inside if-else statements with conditions that are |
private final Set<DefaultResourceLeak<?>> allLeaks = | ||
private final Set<DefaultResourceLeak<?>> allLeaks = isImmutableDisabled()? null : | ||
Collections.newSetFromMap(new ConcurrentHashMap<DefaultResourceLeak<?>, Boolean>()); | ||
|
||
private final ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>(); | ||
private final Set<String> reportedLeaks = | ||
private final ReferenceQueue<Object> refQueue = isImmutableDisabled()? null : new ReferenceQueue<Object>(); | ||
private final Set<String> reportedLeaks = isImmutableDisabled()? null : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't these changes break trackForcibly
?
@franz1981 I am still not convinced we need to add this extra complexity for the relativ small win... wdyt ? |
I have yet to address the changes as suggested by @zakkak and verify what happen on native image; I have some gut feeling that for native image this could reduce memory footprint (which depends on recheability) quite a bit. |
Motivation:
Unstrusted fields from the JDK perspective are more costy and subsequent decisions cannot be constant folded
Modifications:
Create a new sys property to set it up
Result:
Better performance and likely smaller native images for DISABLED cases