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

com.tangosol.io.nio.DirectBufferManager Maven / Gradle / Ivy

There is a newer version: 24.09
Show newest version
/*
 * Copyright (c) 2000, 2020, Oracle and/or its affiliates.
 *
 * Licensed under the Universal Permissive License v 1.0 as shown at
 * http://oss.oracle.com/licenses/upl.
 */

package com.tangosol.io.nio;


import com.tangosol.coherence.config.Config;

import java.nio.ByteBuffer;


/**
* Manages a growable direct ByteBuffer.
*
* @see ByteBuffer
*
* @author cp  2002.09.16
*
* @since Coherence 2.2
*
* @deprecated use {@link com.tangosol.io.journal.JournalBinaryStore JournalBinaryStore}
*             instead
*/
@Deprecated
public class DirectBufferManager
        extends AbstractBufferManager
    {
    // ----- constructors ---------------------------------------------------

    /**
    * Construct a DirectBufferManager that supports a buffer of a certain
    * initial and maximum size.
    *
    * @param cbInitial  the initial size
    * @param cbMaximum  the maximum size
    */
    public DirectBufferManager(int cbInitial, int cbMaximum)
        {
        super(cbInitial, cbMaximum);
        allocateBuffer();
        }


    // ----- internal -------------------------------------------------------

    /**
    * Allocate a new buffer, copying old data if there is any.
    *
    * @see ByteBuffer#allocateDirect(int) ByteBuffer.allocateDirect()
    */
    protected void allocateBuffer()
        {
        long       lStart = System.currentTimeMillis();
        ByteBuffer bufOld = getBuffer();
        ByteBuffer bufNew = MODE_DEBUG ? ByteBuffer.allocate(getCapacity())
                                       : ByteBuffer.allocateDirect(getCapacity());
        int cbOld         = 0;
        int cbNew         = bufNew.capacity();
        if (bufOld != null)
            {
            int ofOld  = bufOld.position();
            cbOld      = bufOld.capacity();
            int cbCopy = Math.min(cbOld, cbNew);
            bufOld.position(0);
            if (cbOld > cbNew)
                {
                int    cbBuf = Math.max(cbCopy, 16384);
                byte[] abBuf = new byte[cbBuf];
                while (cbCopy > 0)
                    {
                    int cbChunk = Math.min(cbBuf, cbCopy);
                    bufOld.get(abBuf, 0, cbChunk);
                    bufNew.put(abBuf, 0, cbChunk);
                    cbCopy -= cbChunk;
                    }
                }
            else
                {
                bufNew.put(bufOld);
                }

            if (ofOld < cbNew)
                {
                bufNew.position(ofOld);
                }
            }

        // Keep track of the amount of "detached", possibly not freed data;
        // see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4857305
        // COH-2495
        s_cbUncollected += cbOld;
        s_cAllocations++;

        setBuffer(bufNew);

        cleanupBuffers();

        long cMillis = System.currentTimeMillis() - lStart;
        if (cMillis > 100L)
            {
            log("Buffer [" + s_cAllocations + "] allocated grew from " +
                    cbOld + " to " + cbNew + " bytes, took " + cMillis + " ms.");
            }
        s_lTotalAllocationTime += cMillis;
        }

    /**
    * Determines if and how to induce the JVM to run finalizers. This allows
    * to somewhat mitigate
    * 
    * a known JDK bug.
    * 

* When the amount of uncollected garbage reaches the threshold indicated * by {@link #getCleanupThreshold() the cleanup threshold} frequency, * induce the GC. In a 64-bit VMs this issue is probably reduced to a * minimum. */ protected void cleanupBuffers() { Runtime runtime = Runtime.getRuntime(); if (s_cbUncollected > (runtime.maxMemory() * getCleanupThreshold())) { switch (getCleanupMethod()) { case CLEANUP_FINALIZERS: runtime.runFinalization(); break; case CLEANUP_GC: runtime.gc(); break; default: break; } s_cbUncollected = 0; } } // ----- accessors ----------------------------------------------------- /** * Return the total time spent allocating buffers, copying the previous * content and cleaning up uncollected buffers. * * @return the number of milliseconds spent in allocating, copying and * cleaning up uncollected buffers */ public static long getTotalAllocationTime() { return s_lTotalAllocationTime; } /** * Return the total number of buffers allocated by the DirectBufferManager. * * @return the total number of allocations */ public static int getAllocations() { return s_cAllocations; } /** * Return the method used for buffers cleanup when the threshold is met. *

* The possible return values are: *

    *
  • CLEANUP_FINALIZERS - use Runtime.runFinalization() (default);
  • *
  • CLEANUP_GC - use Runtime.gc();
  • *
  • CLEANUP_NONE - do not perform any cleanup.
  • *
* * @return one of the CLEANUP_* constants representing the cleanup method */ public static int getCleanupMethod() { return s_nCleanupMethod; } /** * Set the method to be used for buffers cleanup when the threshold is met. * * @param nCleanupMethod a value representing the cleanup method; valid * values are the CLEANUP_* constants * * @throws IllegalArgumentException if passed value is not a valid * CLEANUP_* constant */ protected static void setCleanupMethod(int nCleanupMethod) { if (nCleanupMethod < CLEANUP_NONE || nCleanupMethod > CLEANUP_GC) { throw new IllegalArgumentException("Invalid cleanup method: " + nCleanupMethod); } s_nCleanupMethod = nCleanupMethod; } /** * Return the value used to calculate the size threshold for the * uncollected buffers that triggers a cleanup operation. Cleanup is * performed when the total size of uncollected memory has grown over the * product of this value and the maximum Java heap size. * * @return a value between 0.0 and 1.0 used to calculate the cleanup * frequency */ public static float getCleanupThreshold() { return s_fCleanupThreshold; } /** * Determines how often, to run the {@link #cleanupBuffers()} method. * Cleanup is performed when the uncollected memory has grown over the * product of this value and the maximum Java heap size. * * @param flCleanupThreshold a value between 0.0 and 1.0 used to * calculate the cleanup frequency * * @throws IllegalArgumentException if the passed value is not valid */ protected static void setCleanupThreshold(float flCleanupThreshold) { if (flCleanupThreshold < 0.0 || flCleanupThreshold > 1.0) { throw new IllegalArgumentException("Invalid cleanup threshold: " + flCleanupThreshold); } s_fCleanupThreshold = flCleanupThreshold; } // ----- constants ------------------------------------------------------ /** * Do not perform any buffer cleanup. */ public static final int CLEANUP_NONE = 0; /** * Use Runtime.runFinalization() to trigger finalization (default). */ public static final int CLEANUP_FINALIZERS = 1; /** * Use Runtime.gc() to trigger finalization. */ public static final int CLEANUP_GC = 2; /** * Set to true to use on-heap storage, false to use off-heap. */ protected static final boolean MODE_DEBUG = false; // ----- data members --------------------------------------------------- /** * Total amount of memory that have not been collected yet. */ protected static volatile long s_cbUncollected; /** * Total time spent while allocating buffers, copying the previous content * and cleaning buffers. */ private static volatile long s_lTotalAllocationTime; /** * Total number of buffer allocations made by the DirectBufferManager. */ private static volatile int s_cAllocations; /** * The type of cleanup method (CLEANUP_* constants). */ private static int s_nCleanupMethod; /** * Used to calculate the cleanup frequency. */ private static float s_fCleanupThreshold; /** * Initialize the cleanup related values. */ static { setCleanupThreshold(Config.getFloat("coherence.nio.cleanup.frequency", 0.10F)); String sCleanupMethod = Config.getProperty("coherence.nio.cleanup.method", "FINALIZERS"); if (sCleanupMethod.equalsIgnoreCase("FINALIZERS")) { setCleanupMethod(CLEANUP_FINALIZERS); } else if (sCleanupMethod.equalsIgnoreCase("GC")) { setCleanupMethod(CLEANUP_GC); } else { setCleanupMethod(CLEANUP_NONE); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy