private void tryReturnToPool(T object, ObjectId objectId, Cleaner cleaner, ObjectLeakNotifier notifier) { long currentPoolSize; do { currentPoolSize = poolSize.get(); if (currentPoolSize >= objectsCacheMaxCount) { notifier.disable(); // Effectively does nothing, because notifier is disabled above. The purpose of this call is to deregister the // cleaner from the internal global linked list of all cleaners in the JVM, and let it be reclaimed itself. cleaner.clean(); // Important to use the objectId after notifier.disable() (in the logging statement below), otherwise VM may // already decide that the objectId is unreachable and run Cleaner before notifier.disable(), that would be // reported as a false-positive "leak". Ideally reachabilityFence(objectId) should be inserted here. log.debug("cache num entries is exceeding in [%s], objectId [%s]", this, objectId); return; } } while (!poolSize.compareAndSet(currentPoolSize, currentPoolSize + 1)); if (!objects.offer(new ObjectResourceHolder(object, objectId, cleaner, notifier))) { impossibleOffsetFailed(object, objectId, cleaner, notifier); } }
private ObjectResourceHolder makeObjectWithHandler() { T object = generator.get(); ObjectId objectId = new ObjectId(); ObjectLeakNotifier notifier = new ObjectLeakNotifier(this); // Using objectId as referent for Cleaner, because if the object itself (e. g. ByteBuffer) is leaked after taken // from the pool, and the ResourceHolder is not closed, Cleaner won't notify about the leak. return new ObjectResourceHolder(object, objectId, Cleaner.create(objectId, notifier), notifier); }
private void tryReturnToPool(T object, ObjectId objectId, Cleaner cleaner, ObjectLeakNotifier notifier) { long currentPoolSize; do { currentPoolSize = poolSize.get(); if (currentPoolSize >= objectsCacheMaxCount) { notifier.disable(); // Effectively does nothing, because notifier is disabled above. The purpose of this call is to deregister the // cleaner from the internal global linked list of all cleaners in the JVM, and let it be reclaimed itself. cleaner.clean(); // Important to use the objectId after notifier.disable() (in the logging statement below), otherwise VM may // already decide that the objectId is unreachable and run Cleaner before notifier.disable(), that would be // reported as a false-positive "leak". Ideally reachabilityFence(objectId) should be inserted here. log.debug("cache num entries is exceeding in [%s], objectId [%s]", this, objectId); return; } } while (!poolSize.compareAndSet(currentPoolSize, currentPoolSize + 1)); if (!objects.offer(new ObjectResourceHolder(object, objectId, cleaner, notifier))) { impossibleOffsetFailed(object, objectId, cleaner, notifier); } }
private ObjectResourceHolder makeObjectWithHandler() { T object = generator.get(); ObjectId objectId = new ObjectId(); ObjectLeakNotifier notifier = new ObjectLeakNotifier(this); // Using objectId as referent for Cleaner, because if the object itself (e. g. ByteBuffer) is leaked after taken // from the pool, and the ResourceHolder is not closed, Cleaner won't notify about the leak. return new ObjectResourceHolder(object, objectId, Cleaner.create(objectId, notifier), notifier); }