---
layout: doc_page
---
<!--
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you 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.
-->
## Memory Package

### Introduction

The primary objective for the _Memory Package_ is to allow high-performance read-write access to Java "off-heap" memory 
(also referred to as _direct_, or _native_ memory). However, as documented below, this package has a rich set of other
capabilities as well.

#### Versioning
The _DataSketches_ memory package has its own repository and is released with its own jars in _Maven Central_ 
(groupId=org.apache.datasketches, artifactId=datasketches-memory).
This document applies to the memory package versions 0.10.0 and after. 

#### Naming Conventions
To avoid confusion in the documentation the capitalized _Memory_ refers to the code in the 
Java _org.apache.datasketches.memory_ package, and the uncapitalized _memory_ refers to computer memory in general. 
There is also a class _org.apache.datasketches.memory.Memory_ that should not be confused with the _org.apache.datasketches.memory_ package.
In the text, sometimes _Memory_ refers to the entire package and sometimes to the specific class, 
but it should be clear from the context.


For compatibility and ease-of-use the _Memory_ API can also be used to manage data structures that are 
contained in Java on-heap primitive arrays, memory mapped files, or _ByteBuffers_.

#### Driving Rationale: Large Java Systems Require "Off-Heap" Memory
The hardware systems used in big data environments can be quite large approaching a terabyte 
of RAM and 24 or more CPUs, each of which can manage two threads.
Most of that memory is usually dedicated to selected partitions of data, 
which can even be orders of magnitude larger. 
How the system designers select the partitions of the data to be in RAM over time is quite complex 
and varies considerably based on the specific objectives of the systems platform. 

In these very large data environments managing how the data gets copied into RAM,
when it is considered obsolete, and when it can be written 
over by newer or different partitions of data, are important aspects of the systems design. 
Having the JVM manage these large chunks of memory is often problematic. 
For example, the Java specification requires that a new allocation of memory be cleared before
it can be used. When the allocations become large this alone can result in large pauses in a
running application, especially if the application does not require that the memory be cleared. 
Repeated allocation and deallocation of large memory blocks can also cause large garbage collection pauses,
which can have major impact on the performance of real-time systems. 
As a result, it is often the case that the system designers need to manage these large chunks of 
memory directly.  

The JVM has a very sophisticated heap management process and works very well for many 
general purpose programming tasks. 
However, for very large systems that have critical latency requirements, 
utilizing off-heap memory efficiently becomes a requirement. 

Java does not permit normal java processes direct access to off-heap memory (except as noted below). Nonetheless, 
in order to improve performance, many internal Java classes leverage a low-level, restricted
class called (unfortunately) "_Unsafe_", which does exactly that. The methods of _Unsafe_
are native methods that are initially compiled into C++ code.  The JIT compiler
replaces this C++ code with assembly language instructions called "intrinsics", which
can be just a single CPU instruction. This results in superior runtime performance that is
very close to what could be achieved if the application was written in C++.

The _Memory_ package is essentially an extension of _Unsafe_ and wraps most of the 
primitive get and put methods and a few specialized methods into a convenient API 
organized around an allocated block of native memory.

The only "official" alternative available to systems developers is to use the Java _ByteBuffer_ class 
that also allows access to off-heap memory.  However, the _ByteBuffer_ API is extremely limited
and contains serious defects in its design and traps that many users of the _ByteBuffer_ class unwittingly 
fall into, which results in corrupted data. This _Memory Package_ has been designed to be a 
replacement for the _ByteBuffer_ class.

Using the _Memory_ package cannot be taken lightly, as the systems developer must now be 
aware of the importance of memory allocation and deallocation and make sure these resources 
are managed properly. To the extent possible, this _Memory Package_ has been designed leveraging Java's own
_AutoCloseable_, and _Cleaner_ and also tracks when allocated memory has been freed and provides safety checks
against the dreaded "use-after-free" case.

### Architecture
The Memory package is designed around two major types of entities:

  * _Resources_: A _Resource_ is a collection of consecutive bytes. 
  * _APIs_: An API is a programming interface for reading and writing to a resource.

#### Resourses
The _Memory_ package defines 4 _Resources_, which at their most basic level can be viewed as a collection of consecutive bytes.

  * Primitive on-heap arrays: _boolean[], byte[], char[], short[], int[], long[], float[], double[]_.
  * Java _ByteBuffers_.
  * Off-heap memory. Also called "native" or "direct" memory.
  * Memory-mapped files. 

It should be noted at the outset that the off-heap memory and the memory-mapped file resources require special handling with respect to allocation and deallocation. 
The _Memory Package_ has been designed to access these resources leveraging the Java _AutoCloseable_ interface and the Java internal _Cleaner_ class, 
which also provides the JVM with mechanisms for tracking overall use of off-heap memory. 

#### APIs
The _Memory_ package defines 5 principal APIs for accessing the above resources.

  * _Memory_: Read-only access using byte offsets from the start of the resource.
  * _WritableMemory_: Read/write access using byte offsets from the start of the resource.
  * _BaseBuffer_: Positional API that supports _Buffer_ and _WritableBuffer_ using four key positional values:
  _start_, _position_, _end_, and _capacity_, and a rich set of methods to access them.
  * _Buffer_: Read-only access using the _BaseBuffer_ positional API.
  * _WritableBuffer_: Read-write access using the _BaseBuffer_ positional API.

These 5 principal APIs and the four Resources are then multiplexed into 32 API/Resource combinations as follows:

  * Resource: on-heap, _ByteBuffer_, off-heap, memory-mapped files.
  * Memory versus Buffer APIs
  * Read-only versus read-write APIs
  * Little-Endian versus Big-Endian APIs for multibyte primitives

#### Design Goals 
These are the major design goals for the _Memory Package_.

  * __Common API__. The APIs should be agnostic to the chosen resource, with only a few minor exceptions. 
  * __Performance is critical__. The architecture has been specifically designed to eliminate unnecessary object and interface redirection.
  This allows the JIT compiler to collapse abstract hierarchies down to a "base class" at runtime, eliminating all call overhead. 
  This is why the "APIs" are defined using abstract class hierarchies versus using interfaces, which would force the JIT compiler to create 
  virtual jump tables in the emitted code. This has been proven to provide substantial improvement in runtime performance. 
  * __Eliminate unnecessary copies__. This is also a performance goal. All the API access classes are essentially "views" into the underlying resource. 
  For example: switching from a "Buffer" API to a "Memory" API, or from a writable API to a read-only API, or from a big-endian to a little-endian
  view of the resource does not involve any copying or movement of the underlying data.
  * __Data type agnostic__.  Contrary to the Java specification, the underlying resource can be simultaneously viewed as a collection of bytes, ints, longs, etc, at arbitrary byte offsets. This is similar to the _union_ construct in C. The _ByteBuffer_ already allows this, but its implementation is limited and flawed.
  * __Efficient read-only vs read-write implementation__.  To eliminate duplicate code and unnecessary exceptions we have the writable API extend the read-only API. 
  This means that the read-only API has no writable methods, thus accidental writing from this API is not possible. Given a writable instance, 
  converting it to a read-only instance is a simple cast at compile time. It also means that a user could intentionally down-cast a read-only instance into a writable instance. It has been our experience, however, that this is very rare, and usually only used to obtain an attribute that would otherwise only be obtainable from the writable interface, such as a reference to the underlying array object. For example, this is used internally within our library to eliminate unnecessary data copies during serialization.   
  * __Endianness is immutable and remembered when switching views__.  This was an intentional design choice in response to the way the _ByteBuffer_ was designed, 
  which allows the user to change endianness dynamically. We have found the _ByteBuffer_ implementation to be a major source of data corruption problems that have proven to be nearly impossible to fix. 
  * __Provide both absolute offset addressing and relative positional addressing__. The _Memory_ hierarchy provides the absolute offset addressing API and the 
  _Buffer_ hierarchy provides the relative postional addressing API. These two addressing mechanisms can be switched back and forth without changing the fundamental connection to the
  underlying resource.
  * __Regional views__. Any resource can be subdivided into smaller _regions_. This is similar to the _ByteBuffer.slice()_ capability except it is more flexible.
  

#### Diagram of the Core Hierarchy
This includes both package-private classes as well as public classes, but should help the user understand the inner workings of the _Memory Package_.

<img class="doc-img-full" src="{{site.docs_img_dir}}/memory/CoreHierarchy.png" alt="CoreHierarchy.png" />

### Mapping a Resource to an API
There are two different ways to map a resource to an API. 

  * The first uses methods for allocating on-heap arrays or heap or direct _ByteBuffers_.
  * The second way to map a resource to an API is for _AutoCloseable_ resources, such as off-heap memory and memory-mapped files. 
Special classes called "_Handles_" are used to manage the _AutoCloseable_ properties.

#### Examples for Accessing Primitive On-heap Array Resources
```java
    //use static methods to map a new array of 1024 bytes to the WritableMemory API
    WritableMemory wmem = WritableMemory.allocate(1024);
    
    //Or by wrapping an existing primitive array:
    byte[] array = new byte[] {1, 0, 0, 0, 2, 0, 0, 0};
    Memory mem = Memory.wrap(array);
    assert mem.getInt(0) == 1;
    assert mem.getInt(4) == 2;
```


The following illustrates that the underlying structure of the resource is _bytes_ but we can read it as
_ints, longs, char_, or whatever. This is similar to a C _UNION_, which allows multiple data types
to access the underlying bytes. This isn't allowed in Java! 
So you have to keep careful track of your own structure and the appropriate byte offsets. For example:

```java
    byte[] arr = new byte[16];
    WritableMemory wmem = WritableMemory.writableWrap(arr);
    wmem.putByte(1, (byte) 1);
    int v = wmem.getInt(0);
    assert ( v == 256 );

    arr[9] = 3; //you can also access the backing array directly
    long v2 = wmem.getLong(8);
    assert ( v2 == 768L);
```


Reading and writing multibyte primitives requires an assumption about byte ordering or _endianness_. 
The default endianness is _ByteOrder.nativeOrder()_, which for most CPUs is _ByteOrder.LITTLE\_ENDIAN_.
Additional APIs are also available for reading and writing in non-native endianness.

All of the APIs provide a useful _toHexString(...)_ method to assist you in viewing the data in your resources.

#### Examples for Accessing ByteBuffers
Mapping a _ByteBuffer_ resource to the _WritableMemory_ API.  
Here we write the _WritableBuffer_ and read from both the _ByteBuffer_ and the _WritableBuffer_.

```java
    @Test
    public void simpleBBTest() {
      int n = 1024; //longs
      byte[] arr = new byte[n * 8];
      ByteBuffer bb = ByteBuffer.wrap(arr);
      bb.order(ByteOrder.nativeOrder());
      
      WritableBuffer wbuf = WritableBuffer.writableWrap(bb);
      for (int i = 0; i < n; i++) { //write to wbuf
        wbuf.putLong(i);
      }
      wbuf.resetPosition();
      for (int i = 0; i < n; i++) { //read from wbuf
        long v = wbuf.getLong();
        assertEquals(v, i);
      }
      for (int i = 0; i < n; i++) { //read from BB
        long v = bb.getLong();
        assertEquals(v, i);
      }
    }
```

#### Accessing _AutoCloseable_ Resources

The following diagram illustrates the relationships between the _Map_ and _Handle_ hierarchies. 
The _Map_ interfaces are not public, nonetheless this should help understand their function.

<img class="doc-img-full" src="{{site.docs_img_dir}}/memory/MapAndHandleHierarchy.png" alt="MapAndHandleHierarchy.png" />

##### Accessing Off-Heap Resources  
Direct allocation of off-heap resources requires that the resource be closed when finished.
This is accomplished using a _WritableDirectHandle_ that implements the Java _AutoCloseable_ interface. 
Note that this example leverages the try-with-resources statement to properly close the resource.

```java
    @Test
    public void simpleAllocateDirect() throws Exception {
      int longs = 32;
      try (WritableHandle wh = WritableMemory.allocateDirect(longs << 3)) {
        WritableMemory wMem1 = wh.getWritable();
        for (int i = 0; i<longs; i++) {
          wMem1.putLong(i << 3, i);
          assertEquals(wMem1.getLong(i << 3), i);
        }
      }
    }
```

Note that these direct allocations can be larger than 2GB.

##### Memory Mapped File Resources
Memory-mapped files are resources that also must be closed when finished.
This is accomplished using a _MapHandle_ that implements the Java _AutoClosable_ interface.
In the src/test/resources directory of the memory-X.Y.Z-test-sources.jar there is a file called _GettysburgAddress.txt_.
Note that this example leverages the _try-with-resources_ statement to properly close the resource.
To print out Lincoln's Gettysburg Address:

```java
    @Test
    public void simpleMap() throws Exception {
      File file = new File(getClass().getClassLoader().getResource("GettysburgAddress.txt").getFile());
      try (MapHandle h = Memory.map(file)) {
        Memory mem = h.get();
        byte[] bytes = new byte[(int)mem.getCapacity()];
        mem.getByteArray(0, bytes, 0, bytes.length);
        String text = new String(bytes);
        System.out.println(text);
      }
    }
```

The following test does the following:

1. Creates a off-heap _WritableMemory_ and preloads it with 4GB of consecutive longs as a candidate source.
2. Creates an empty file, and maps it to a memory-mapped space also of 4GB as the destination.
3. Copies the source to the destination in a single operation. No extra copies required.

```java
    @Test
    public void copyOffHeapToMemoryMappedFile() throws Exception {
      long bytes = 1L << 32; //4GB
      long longs = bytes >>> 3;
  
      File file = new File("TestFile.bin");
      if (file.exists()) { file.delete(); }
      assert file.createNewFile();
      assert file.setWritable(true, false);
      assert file.isFile();
      file.deleteOnExit();  //comment out if you want to examine the file.
  
      try (
          WritableMapHandle dstHandle
            = WritableMemory.writableMap(file, 0, bytes, ByteOrder.nativeOrder());
          WritableHandle srcHandle = WritableMemory.allocateDirect(bytes)) {
  
        WritableMemory dstMem = dstHandle.getWritable();
        WritableMemory srcMem = srcHandle.getWritable();
  
        for (long i = 0; i < (longs); i++) {
          srcMem.putLong(i << 3, i); //load source with consecutive longs
        }
  
        srcMem.copyTo(0, dstMem, 0, srcMem.getCapacity()); //off-heap to off-heap copy
  
        dstHandle.force(); //push any remaining to the file
  
        //check end value
        assertEquals(dstMem.getLong((longs - 1L) << 3), longs - 1L);
      }
    }
```

### Regions and WritableRegions
Similar to the _ByteBuffer slice()_, one can create a region or writable region, 
which is a view into the same underlying resource. 

```java
    @Test
    public void checkRORegions() {
      int n = 16;
      int n2 = n / 2;
      long[] arr = new long[n];
      for (int i = 0; i < n; i++) { arr[i] = i; }
      Memory mem = Memory.wrap(arr);
      Memory reg = mem.region(n2 * 8, n2 * 8);
      for (int i = 0; i < n2; i++) {
        assertEquals(reg.getLong(i * 8), i + n2);
      }
    }
```

### Using the Library

See the project [README](https://github.com/apache/datasketches-memory/blob/master/README.md) for further instructions on how to use the Datasketches Memory library in your own applications.  
