All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.openhft.chronicle.hash.impl.ContextHolder Maven / Gradle / Ivy

There is a newer version: 3.26ea4
Show newest version
/*
 * Copyright 2012-2018 Chronicle Map Contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.openhft.chronicle.hash.impl;

import net.openhft.chronicle.hash.impl.stage.hash.ChainingInterface;

/**
 * A simple wrapper of {@link ChainingInterface}, the ChainingInterface field could be set to null.
 * 

*

Motivation

*

{@link net.openhft.chronicle.map.ChronicleMap}'s context objects are huge and reference their * own instances of key and value marshallers, which usually have buffers for serialization (e. g. * see {@link net.openhft.chronicle.hash.serialization.impl.SerializableDataAccess}). The contexts * are stored in {@link ThreadLocal}s, which are instance fields of ChronicleMap objects * (see {@link net.openhft.chronicle.map.VanillaChronicleMap#cxt}). We want the context objects to * be eligible for garbage collection as soon as possible after the ChronicleMap object is closed * or becomes unreachable. *

*

In JDK 8 ThreadLocals are implemented using {@link java.lang.ThreadLocal.ThreadLocalMap}, * a hash table with ThreadLocal objects themselves as the keys, weak-referenced. So after * ChronicleMap (hence it's ThreadLocal cxt field) becomes unreachable, context objects should be * eventually removed from ThreadLocalMap and become unreachable, but the current implementation * does some cleanup of ThreadLocalMap lazily and only on ThreadLocal.set(), initialValue() and * remove(), but not on the hot path of ThreadLocal.get(). I. e. if there is not enough "ThreadLocal * activity" within a thread, stale ChronicleMap contexts may not be removed from ThreadLocalMaps * forever, effectively this is a memory leak. *

*

Moreover, if the user of the library closes ChronicleMap with close(), but has ChronicleMap * object leaked, ChronicleMap's ThreadLocal field doesn't become unreachable and the leak of * context objects is "legitimate". *

*

Solution for this is to reference from {@link * net.openhft.chronicle.map.VanillaChronicleMap#cxt} not huge context object directly, but small * ContextHolder object, and clear the reference to context via {@link #clear()} on * ChronicleMap.close() or from {@link sun.misc.Cleaner}'s registered cleaner for ChronicleMap, if * it weren't closed, but becomes unreachable and reclaimed by the garbage collector. * * @see ChronicleHashResources#closeContext(ContextHolder) */ public final class ContextHolder { private ChainingInterface context; public ContextHolder(ChainingInterface context) { this.context = context; } public ChainingInterface get() { return context; } void clear() { context = null; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy