-
Notifications
You must be signed in to change notification settings - Fork 4
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
Object is cleaned too soon during unit testing #93
Comments
@dmitripivkine @tajila fyi, pls take a look. |
Is this test failing with |
This is unlikely GC issue. Sounds as VM (or even JIT potentially). GC does not control set of the roots. |
|
Let me give you code a little less "redacted" to consider. The Cleaner is defined here. public interface KeysProvider
{
Cleaner cleaner = Cleaner.create();
// etc.
} The channel is registered with the Cleaner in this method: public final class GrpcProvider implements KeysProvider
{
// other stuff
@Override
public Keys open (URI locator)
{
try
{
// lots of peculiar configuration parsing
final var builder = Grpc.newChannelBuilder(target,credentials);
builder.defaultLoadBalancingPolicy("round_robin");
builder.defaultServiceConfig(serviceConfig);
final var channel = builder.build();
final var service = new GrpcKeys( getLogger(GrpcKeys.class), newBlockingStub(channel) );
cleaner.register(service,channel::shutdownNow);
return service;
}
catch (Exception e)
{
throw new KeysException("not expected",e);
}
}
} and the JUnit tests as above. |
@babsingh Please take a look at this |
@pedrolamarao Can you provide a micro-test that I can run locally to reproduce the failure? It's needed to generate artifacts for introspecting JVM behavior. |
Below is the testcase that I derived from the above information. I am unable to reproduce the issue.
|
Assuming that
|
The test is new; the Semeru JDK was not recently updated.
I have attached the javacore.20241001.151523.11480.0003.txt |
|
Yes, it reproduces with version 17.0.12+7. Is I may find time to try a minimal reproducer, but not soon. |
Thanks for the core files. I will see if they pin-point the root cause. -Xdump will need to be used in conjunction with jdb to produce core files at specific file/line locations. The below steps highlight this process.
You can set breakpoints through jdb.
|
@pedrolamarao Does the failure go away if we change the GC policy to -Xgcpolicy:nogc and -Xgcpolicy:optthruput? The default GC policy is |
Test results with various
|
@pedrolamarao Would it be possible for you to invoke Since there might not be any active references to the object while the instance method is still executing, the object could potentially be eligible for collection by the GC. If manually invoking the garbage collector (via However, if this issue does not occur with these JDKs, we may need to delve deeper into OpenJ9. The core files only show the final state and don't provide insight into how the JVM reached that state. Further investigation through more active debugging (e.g., logging) may be required, though this approach is typically more tedious and time-consuming. That said, having a micro test that consistently reproduces the issue would significantly ease the process and help narrow down the root cause more quickly.
|
We have a reproducer here: https://github.com/pedrolamarao/semeru-issue-93 With
running |
@pedrolamarao I am getting the below errors. Am I missing steps or dependencies on my end?
|
Sorry, repositories must be coming from environment configuration. |
Marking the receiver object of an instance method ensures that it is not collected by the garbage collector (GC) while the instance method is executing. If the receiver object is not marked, there is a risk that the GC might collect it. In such cases, finalization mechanisms, such as PhantomReferences and Cleaners, could indicate that the object has been collected while it is still in use. This issue is resolved if the receiver object is marked during the execution of its instance method. Fixes: ibmruntimes/Semeru-Runtimes#93 Signed-off-by: Babneet Singh <sbabneet@ca.ibm.com>
I have experimented with the RI to see if it collects the object early similar to OpenJ9. The RI never collected the object even after applying JVM options to make the RI's GC policy aggressive. This issue seems like a bug in OpenJ9 where the receiver object is collected while its instance method is executing. This happens because the receiver object is tagged as an I-slot. eclipse-openj9/openj9#20384 has been opened as a potential fix for this issue. |
Related: ibmruntimes/Semeru-Runtimes#93 Signed-off-by: Babneet Singh <sbabneet@ca.ibm.com>
Related: ibmruntimes/Semeru-Runtimes#93 Signed-off-by: Babneet Singh <sbabneet@ca.ibm.com>
Related: ibmruntimes/Semeru-Runtimes#93 Signed-off-by: Babneet Singh <sbabneet@ca.ibm.com>
Related: ibmruntimes/Semeru-Runtimes#93 Signed-off-by: Babneet Singh <sbabneet@ca.ibm.com>
Related: ibmruntimes/Semeru-Runtimes#93 Signed-off-by: Babneet Singh <sbabneet@ca.ibm.com>
Related: ibmruntimes/Semeru-Runtimes#93 Signed-off-by: Babneet Singh <sbabneet@ca.ibm.com>
j9localmap_LocalBitsForPC is more aggressive than j9localmap_DebugLocalBitsForPC in the way it analyzes and marks local variables as object references. Aggressiveness relates to determining whether a local object is being used at a specific point in the bytecode execution, and this helps optimize garbage collection and runtime performance. In contrast, j9localmap_DebugLocalBitsForPC adopts a conservative approach; it overestimates and plays safe by marking objects alive even if they are not being used. j9localmap_DebugLocalBitsForPC resolves the issue seen in ibmruntimes/Semeru-Runtimes#93. We have run the following benchmarks: Liberty DT8/DT10 Startup & Footprint, JRuby and Nashorn. No performance difference is seen between j9localmap_DebugLocalBitsForPC and j9localmap_LocalBitsForPC. Signed-off-by: Babneet Singh <sbabneet@ca.ibm.com>
j9localmap_LocalBitsForPC is more aggressive than j9localmap_DebugLocalBitsForPC in the way it analyzes and marks local variables as object references. Aggressiveness relates to determining whether a local object is being used at a specific point in the bytecode execution, and this helps optimize garbage collection and runtime performance. In contrast, j9localmap_DebugLocalBitsForPC adopts a conservative approach; it overestimates and plays safe by marking objects alive even if they are not being used. j9localmap_DebugLocalBitsForPC resolves the issue seen in ibmruntimes/Semeru-Runtimes#93. We have run the following benchmarks: Liberty DT8/DT10 Startup & Footprint, JRuby and Nashorn. No performance difference is seen between j9localmap_DebugLocalBitsForPC and j9localmap_LocalBitsForPC. Since there are no side-effects of j9localmap_DebugLocalBitsForPC, this PR makes it OpenJ9's default mapper. Signed-off-by: Babneet Singh <sbabneet@ca.ibm.com>
The change caused problems and was reverted. |
We have a modular system with a service provider scheme.
One of our providers is gRPC-based.
We use a Cleaner to shutdown the managed channel when the provided service is collected.
This is how the provider builds the service:
In our unit testing, there is a test like this:
This test passes in Adoptium and Liberica 11 and 17 JDKs, but fails in Semeru 11 and 17 JDKs with a
Channel shutdownNow invoked
exception. Debugging confirms that this is happening because the Cleaner is calling the Runnable while the test is still running.If we refactor the test to something like this:
the test passes.
It seems that the object is being collected too soon.
The text was updated successfully, but these errors were encountered: