Skip to content
This repository has been archived by the owner on Dec 23, 2023. It is now read-only.

Performance problem with defining finalizer #2045

Closed
spkrka opened this issue Jul 20, 2020 · 4 comments · Fixed by #2043
Closed

Performance problem with defining finalizer #2045

spkrka opened this issue Jul 20, 2020 · 4 comments · Fixed by #2043
Labels

Comments

@spkrka
Copy link
Contributor

spkrka commented Jul 20, 2020

This issue asked for logging of spans that were GC:ed without being closed first.
#1876
And this PR implemented support for that by using finalizers:
#1877

I made the following simple PR to revert that behaviour, but it does not seem like it will be merged:
#2043

The reason for wanting to revert this behavior is that we saw significant performance problems that could be traced back to a large increase of finalization code in GC and also creation of opencensus spans - there is a static synchronization object that is used for that.

Avoiding finalizers is a well established practice - see Effective Java. It's also mentioned in the Checkstyle rule that was disabled: https://checkstyle.sourceforge.io/apidocs/com/puppycrawl/tools/checkstyle/checks/coding/NoFinalizerCheck.html

So instead of going directly for a PR, perhaps it would be better to start a discussion as an issue instead.
Let's try to align on a good solution before making the code changes.

An alternative solution to simply removing the finalization could be to split the class into a base class and two subclasses, where only only of the subclasses overrides finalize and then make the behaviour configurable.
Either you would want to avoid finalizers for performance reasons or you would want to enable finalizers to get logging of misuse of spans. You could even have a mix of it - use sampling to only apply finalizers to a small subset of spans. If there's a systematic problem of not closing spans it would show up anyway.

We could even take it a step further - We could start by not using finalizers but instead keep an atomic counter of currently open spans. If that is continously growing that would be an indicator that we are leaking spans and then we should enable finalizers to assist identifying the problem.

@nilebox
Copy link
Contributor

nilebox commented Sep 22, 2020

Hey @spkrka, thanks for providing details about the issue you're facing due to usage of finalizer in the OpenCensus code.
While #2046 seems to be a workable solution, it is more complicated that we'd prefer since OpenCensus is now in maintenance mode as you may know.

Given the severity of the issue you're having, and the purpose of the finalizer being purely informative (detection and logging of a common bug), I think we would agree to revert the change and merge your PR #2043. Apologies that I didn't realize the issue was causing serious performance problems for you when I initially reviewed that PR.
Does that sound good for you?

@spkrka
Copy link
Contributor Author

spkrka commented Sep 22, 2020

Yes, I think #2043 would be great to merge!

nilebox pushed a commit that referenced this issue Sep 22, 2020
Fixes #2045

This will reduce GC pressure since the VM will not call
Finalizer.register() when creating Span objects.

Since this method is synchronized on a static lock
it can be a source of contention.

It also avoids contention on the same lock when running
runFinalizer() as part of GC
@nilebox
Copy link
Contributor

nilebox commented Sep 22, 2020

Thanks for your patience @spkrka. The fix has been merged, we will try to make a new release within the next few days.

@spkrka
Copy link
Contributor Author

spkrka commented Sep 22, 2020

Great, thanks!

zoercai pushed a commit to zoercai/opencensus-java that referenced this issue Sep 24, 2020
Fixes census-instrumentation#2045

This will reduce GC pressure since the VM will not call
Finalizer.register() when creating Span objects.

Since this method is synchronized on a static lock
it can be a source of contention.

It also avoids contention on the same lock when running
runFinalizer() as part of GC

(cherry picked from commit eab6382)
zoercai added a commit to zoercai/opencensus-java that referenced this issue Sep 25, 2020
Fixes census-instrumentation#2045

This will reduce GC pressure since the VM will not call
Finalizer.register() when creating Span objects.

Since this method is synchronized on a static lock
it can be a source of contention.

It also avoids contention on the same lock when running
runFinalizer() as part of GC

(cherry picked from commit eab6382)
zoercai added a commit to zoercai/opencensus-java that referenced this issue Sep 25, 2020
Fixes census-instrumentation#2045

This will reduce GC pressure since the VM will not call
Finalizer.register() when creating Span objects.

Since this method is synchronized on a static lock
it can be a source of contention.

It also avoids contention on the same lock when running
runFinalizer() as part of GC

(cherry picked from commit eab6382)
zoercai added a commit that referenced this issue Sep 25, 2020
* Remove finalize from RecordEventsSpanImpl (#2043)

Fixes #2045

This will reduce GC pressure since the VM will not call
Finalizer.register() when creating Span objects.

Since this method is synchronized on a static lock
it can be a source of contention.

It also avoids contention on the same lock when running
runFinalizer() as part of GC

(cherry picked from commit eab6382)

* Bump version to 0.27.1

* Bump version to 0.27.2-SNAPSHOT

* Bump version to 0.27.1

* Bump version to 0.27.2-SNAPSHOT
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants