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

Fix(Memory Leak): Remove FencedLockProxy upon FencedLock#destroy [HZ-3039] #25353

Merged
merged 5 commits into from Sep 6, 2023

Conversation

gbarnett-hz
Copy link
Contributor

@gbarnett-hz gbarnett-hz commented Sep 1, 2023

Removes the FencedLockProxy from LockService.proxies after calling legacy semantics of AbstractBlockingService#destroyRaftObject. Previously the FencedLockProxy would be resident in LockService.proxies until the CP system was reset.

Fixes #25344

Backport of: INSERT_LINK_TO_THE_ORIGINAL_PR_HERE

EE PR: INSERT_LINK_TO_THE_EE_PR_HERE

Breaking changes (list specific methods/types/messages):

  • API
  • client protocol format
  • serialized form
  • snapshot format

Checklist:

  • Labels (Team:, Type:, Source:, Module:) and Milestone set
  • Label Add to Release Notes or Not Release Notes content set
  • Request reviewers if possible
  • Send backports/forwardports if fix needs to be applied to past/future releases
  • New public APIs have @Nonnull/@Nullable annotations
  • New public APIs have @since tags in Javadoc

@gbarnett-hz gbarnett-hz marked this pull request as draft September 1, 2023 15:11
@gbarnett-hz gbarnett-hz self-assigned this Sep 1, 2023
@gbarnett-hz gbarnett-hz added the Source: Internal PR or issue was opened by an employee label Sep 1, 2023
@gbarnett-hz gbarnett-hz marked this pull request as ready for review September 4, 2023 08:56
@gbarnett-hz
Copy link
Contributor Author

@arodionov if you can take a look -- if it seems reasonable I will add some testing post-comments.

@arodionov
Copy link
Contributor

Thanks for the PR, Granville.
But, I wonder if it makes sense to even try to remove destroyed proxy objects from the map.

Map with lock proxies created on the server side (if using Hazecast in an embedded mode) or on the client side.
I assume we have such maps only for Lock proxies because: the Lock and a proxy themselves are heavy objects, and the Lock best practice use case, is to try to reuse an existing Lock object.

When the same lock is used from several Hazelcast clients or embedded instances, it means that every client/instance will have a such proxy and this proxy will be added to the maps on each instance:

HazelcastInstance instance1 = Hazelcast.newHazelcastInstance(config);
HazelcastInstance instance2 = Hazelcast.newHazelcastInstance(config);
FencedLock lockInstance1 = instance.getCPSubsystem().getLock("iLock"); // iLock proxy added to proxies Map on lockInstance1
FencedLock lockInstance2 = instance.getCPSubsystem().getLock("iLock"); // iLock proxy added to proxies Map on lockInstance2

Therefore, if we decide to remove the destroyed lock from the proxy's map, it means that it can be removed only from the instance from which the "destroy" method was called.

lockInstance1.destroy(); // iLock proxy removed only from proxies Map on lockInstance1

Other clients/instances will be unaware that the lock has been destroyed.

So, I am wondering, does it make sense to provide a "partial" cleaning at all?

@gbarnett-hz
Copy link
Contributor Author

@arodionov I agree -- even with client changes you only ever cleanup the client that called the destroy. On the server though this will clean up the mapping that is maintained across all instances, so perhaps that's the only place it makes sense?

I had a look at removing the lock proxy in the Python client -- it looks simple but I also had same thought w.r.t. only fixing the client that actually called the destroy.

@arodionov
Copy link
Contributor

Yes, for the embedded mode (server-side) proxies, I think we can proceed with removing the proxy from the proxies map.
In that case, we have a DestroyRaftObjectOp that will be executed at all instances. So we can wipe the proxies map in a consistent way.

Please try to add some tests for the current PR.

@arodionov arodionov added this to the 5.4.0 milestone Sep 4, 2023
@arodionov
Copy link
Contributor

@gbarnett-hz The ReflectionUtils#getFieldValueReflectively may be useful for the test.

@gbarnett-hz
Copy link
Contributor Author

Cheers @arodionov -- will take a look

@arodionov arodionov changed the title Remove FencedLockProxy from LockService.proxies upon FencedLock#destroy Remove FencedLockProxy from LockService.proxies upon FencedLock#destroy [HZ-3039] Sep 5, 2023
Copy link
Contributor

@arodionov arodionov left a comment

Choose a reason for hiding this comment

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

Looks good to me!
Thanks, Granville!

Copy link
Collaborator

@vbekiaris vbekiaris left a comment

Choose a reason for hiding this comment

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

thanks for the fix @gbarnett-hz

FencedLock myLockMember2 = instances[2].getCPSubsystem().getLock(lockName);

myLockMember0.lock();
try {
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: I appreciate the try-finally style, but what is the point when there is no statement in the try block?

@gbarnett-hz gbarnett-hz changed the title Remove FencedLockProxy from LockService.proxies upon FencedLock#destroy [HZ-3039] Fix(Memory Leak): Remove FencedLockProxy upon FencedLock#destroy [HZ-3039] Sep 6, 2023
@gbarnett-hz gbarnett-hz merged commit e301940 into hazelcast:master Sep 6, 2023
8 checks passed
gbarnett-hz added a commit to gbarnett-hz/hazelcast that referenced this pull request Sep 12, 2023
…3039] (hazelcast#25353)

Removes the `FencedLockProxy` from `LockService.proxies` _after_ calling
legacy semantics of `AbstractBlockingService#destroyRaftObject`.
Previously the `FencedLockProxy` would be resident in
`LockService.proxies` until the CP system was reset.

Fixes hazelcast#25344

(cherry picked from commit e301940)
gbarnett-hz added a commit that referenced this pull request Sep 12, 2023
…3039] [5.3.z] (#25421)

Removes the `FencedLockProxy` from `LockService.proxies` _after_ calling
legacy semantics of `AbstractBlockingService#destroyRaftObject`.
Previously the `FencedLockProxy` would be resident in
`LockService.proxies` until the CP system was reset.

Fixes #25344 

Backport of: #25353
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Client and server memory leaks while destroying FencedLocks [HZ-3039]
3 participants