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

com.sleepycat.je.evictor.OffHeapAllocator Maven / Gradle / Ivy

The newest version!
/*-
 * Copyright (C) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
 *
 * This file was distributed by Oracle as part of a version of Oracle Berkeley
 * DB Java Edition made available at:
 *
 * http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
 *
 * Please see the LICENSE file included in the top-level directory of the
 * appropriate version of Oracle Berkeley DB Java Edition for a copy of the
 * license and additional information.
 */

package com.sleepycat.je.evictor;

/**
 * Implemented by off-heap memory allocators.
 *
 * The allocator is responsible for allocating and freeing a block of memory
 * efficiently, maintaining the size of a block, identifying a block by a long
 * integer value (ID), and looking up a memory ID efficiently (in constant
 * time) in order to copy bytes, return the size, or free the block.
 * 

* The allocator is also responsible for compacting memory when necessary to * perform allocations efficiently. A special case is when the off-heap cache * is reduced in size, and memory should be compacted to make memory available * to the OS; the implementation should account for this case. *

* Another responsibility of the allocator is to estimate the RAM usage for all * blocks currently allocated, including overhead and space taken by * fragmentation. It is recognized that this may only be a rough estimate in * some implementations (the default allocator, for example). See * {@link #getUsedBytes}. *

* Note that with the default allocator, the size is not a built-in property * of each block, and the {@link #size} method will be implemented by storing * the size at the front of the block. The {@code size} method is included in * the interface to allow for implementations where a block size property is * naturally available. *

* This interface requires that memory is copied in and out of the Java address * space to make use of the off-heap cache. A future enhancement might involve * adding a way to obtain a ByteBuffer for direct access to the off-heap memory * block, to avoid the copy if this is possible in some implementations. In the * default implementation, this is not practical without using non-public JVM * internals and risking incompatibilities. *

* All methods in the allocator must be thread safe, and contention among * threads should be minimized. *

* The memory blocks are not assumed to be fast access RAM and in particular * might be NVRAM. JE makes an effort to only copy memory to/from the block * when necessary, and to use single larger copy operations rather than * multiple smaller copy operations. */ public interface OffHeapAllocator { class OffHeapOverflowException extends Exception {} /** * Sets the maximum size of the off-heap cache, to be used as a hint for * the creation of implementation specific data structures. * * The maximum cache size is the amount of RAM that the app would like to * use for the off-heap cache, at the gross level of dividing up the RAM on * a machine among processes, the off-heap cache, the file system cache, * etc. Because there is overhead with any allocation scheme, less bytes * will actually be available for memory blocks created with the {@link * #allocate} method. In other words, JE will not assume that it can * allocate blocks totaling the specified maximum size. See {@link * #getUsedBytes }. *

* This method is always called once before any other method is called. It * may be called more than once if the off-heap cache is resized by the * app. * * @see #allocate(int) */ void setMaxBytes(long maxBytes); /** * Returns an estimate of the amount of RAM used by the cache, including * the metadata and block overhead used by the implementation, as well as * any free space needed for performing compaction. * * This method should not cause thread contention when called frequently * from multiple threads. A volatile long field is the suggested * implementation. * * @see #allocate(int) */ long getUsedBytes(); /** * Allocates a block of a given size and returns its ID. * * The bytes of the memory block must be initialized to zero. *

* Note that because the used cache size is only an estimate, and in fact * the maximum size might not actually be available (due to memory use by * other processes when using the default allocator, for example), then the * {@link #allocate} method may fail (thrown an exception) even when the * used size is less than the maximum bytes (the value passed to {@link * #setMaxBytes}). JE handles this situation as follows. *

* JE uses an internal off-heap cache size limit to determine when to * perform eviction (which frees off-heap blocks). The limit is * initialized to the value passed to {@link #setMaxBytes}. JE calls * {@link #getUsedBytes()} to determine when to evict memory from the * cache. If the used bytes by grows very close to the limit or exceeds * it, JE will perform off-heap cache eviction. JE will make a best effort * not to call the {@link #allocate} method when the used size exceeds * the limit. *

* If an allocation failure occurs (i.e., this method throws an * exception), JE adjusts the limit downward to account for the * inaccuracies discussed above. When a RuntimeException is thrown, the * limit is set to the used size; when an OutOfMemoryError is thrown, the * limit is set to the used size minus the {@link * com.sleepycat.je.EnvironmentConfig#OFFHEAP_EVICT_BYTES}. This adjustment * should ensure that JE eviction occurs and prevent frequent allocation * failures and associated exception handling. * TODO: This never happens because Linux kills the process *

* * @return non-zero memory ID, or zero when the memory cannot be allocated. * * @throws OffHeapOverflowException if the block cannot be allocated * because the max size has been reached. The internal off-heap cache * size limit will be set as described above. * * @throws OutOfMemoryError if the block cannot be allocated because no * system memory is available. The internal off-heap cache size limit will * be set as described above. In addition, a SEVERE message for the * exception will be logged. * * @see #getUsedBytes */ long allocate(int size) throws OutOfMemoryError, OffHeapOverflowException; /** * Frees a block previously allocated and returns the size freed, including * any overhead for the block that is now free. */ int free(long memId); /** * Returns the size of an allocated block. */ int size(long memId); /** * Returns the size of an allocated block plus any overhead for the block. */ int totalSize(long memId); /** * Copies bytes from an allocated block to a Java byte array. */ void copy(long memId, int memOff, byte[] buf, int bufOff, int len); /** * Copies bytes from a Java byte array to an allocated block. */ void copy(byte[] buf, int bufOff, long memId, int memOff, int len); /** * Copies bytes from one allocated block to another. */ void copy(long fromMemId, int fromMemOff, long toMemId, int toMemOff, int len); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy