0
# Memory Management
1
2
Apache Fury's memory management system provides high-performance binary buffer operations with platform-specific optimizations and efficient memory access patterns.
3
4
## MemoryBuffer
5
6
The core buffer class for efficient binary data operations with both heap and off-heap memory support.
7
8
```java { .api }
9
public class MemoryBuffer {
10
// Buffer creation
11
public static MemoryBuffer newHeapBuffer(int size);
12
public static MemoryBuffer newDirectBuffer(int size);
13
14
// Basic read/write operations
15
public void writeByte(byte value);
16
public byte readByte();
17
public void writeBoolean(boolean value);
18
public boolean readBoolean();
19
public void writeChar(char value);
20
public char readChar();
21
public void writeShort(short value);
22
public short readShort();
23
public void writeInt(int value);
24
public int readInt();
25
public void writeLong(long value);
26
public long readLong();
27
public void writeFloat(float value);
28
public float readFloat();
29
public void writeDouble(double value);
30
public double readDouble();
31
32
// Array operations
33
public void writeBytes(byte[] bytes);
34
public void writeBytes(byte[] bytes, int offset, int length);
35
public byte[] readBytes(int length);
36
public void readBytes(byte[] bytes, int offset, int length);
37
38
// String operations
39
public void writeString(String str);
40
public String readString();
41
42
// Position management
43
public int writerIndex();
44
public void writerIndex(int writerIndex);
45
public int readerIndex();
46
public void readerIndex(int readerIndex);
47
public void resetWriterIndex();
48
public void resetReaderIndex();
49
50
// Buffer state
51
public int size();
52
public int capacity();
53
public int remain();
54
public boolean isEmpty();
55
56
// Buffer operations
57
public void clear();
58
public void reset();
59
public byte[] toByteArray();
60
public ByteBuffer asByteBuffer();
61
}
62
```
63
64
## Memory Utilities
65
66
Platform-specific memory operations and utilities.
67
68
```java { .api }
69
public class MemoryUtils {
70
// Platform detection
71
public static boolean isLittleEndian();
72
public static boolean isBigEndian();
73
74
// Memory allocation utilities
75
public static long allocateMemory(long size);
76
public static void freeMemory(long address);
77
78
// Memory copy operations
79
public static void copyMemory(long srcAddress, long destAddress, long length);
80
public static void copyMemory(Object src, long srcOffset, Object dest, long destOffset, long length);
81
82
// Bounds checking utilities
83
public static void checkBounds(int index, int length, int capacity);
84
85
// Platform-specific optimizations
86
public static boolean isAligned(long address, int alignment);
87
public static long alignAddress(long address, int alignment);
88
}
89
```
90
91
## Platform
92
93
Low-level platform operations using Unsafe for maximum performance.
94
95
```java { .api }
96
public class Platform {
97
// Direct memory access constants
98
public static final boolean LITTLE_ENDIAN;
99
public static final int BYTE_ARRAY_OFFSET;
100
public static final int INT_ARRAY_OFFSET;
101
public static final int LONG_ARRAY_OFFSET;
102
103
// Memory operations
104
public static byte getByte(long address);
105
public static void putByte(long address, byte value);
106
public static int getInt(long address);
107
public static void putInt(long address, int value);
108
public static long getLong(long address);
109
public static void putLong(long address, long value);
110
111
// Array access
112
public static byte getByte(Object array, long offset);
113
public static void putByte(Object array, long offset, byte value);
114
public static int getInt(Object array, long offset);
115
public static void putInt(Object array, long offset, int value);
116
}
117
```
118
119
## Endianness Utilities
120
121
Utilities for handling byte order and endianness conversions.
122
123
```java { .api }
124
public class LittleEndian {
125
public static short getShort(byte[] bytes, int index);
126
public static void putShort(byte[] bytes, int index, short value);
127
public static int getInt(byte[] bytes, int index);
128
public static void putInt(byte[] bytes, int index, int value);
129
public static long getLong(byte[] bytes, int index);
130
public static void putLong(byte[] bytes, int index, long value);
131
}
132
133
public class BigEndian {
134
public static short getShort(byte[] bytes, int index);
135
public static void putShort(byte[] bytes, int index, short value);
136
public static int getInt(byte[] bytes, int index);
137
public static void putInt(byte[] bytes, int index, int value);
138
public static long getLong(byte[] bytes, int index);
139
public static void putLong(byte[] bytes, int index, long value);
140
}
141
```
142
143
## Buffer Utilities
144
145
Additional utilities for working with ByteBuffer and buffer operations.
146
147
```java { .api }
148
public class ByteBufferUtil {
149
// ByteBuffer creation
150
public static ByteBuffer allocateDirect(int capacity);
151
public static ByteBuffer wrap(byte[] array);
152
153
// Buffer operations
154
public static void clear(ByteBuffer buffer);
155
public static byte[] toArray(ByteBuffer buffer);
156
public static int remaining(ByteBuffer buffer);
157
158
// Endianness handling
159
public static ByteOrder getByteOrder(ByteBuffer buffer);
160
public static void setByteOrder(ByteBuffer buffer, ByteOrder order);
161
}
162
```
163
164
## Usage Examples
165
166
### Basic Buffer Operations
167
168
```java
169
import org.apache.fury.memory.MemoryBuffer;
170
171
// Create heap buffer
172
MemoryBuffer buffer = MemoryBuffer.newHeapBuffer(1024);
173
174
// Write primitive values
175
buffer.writeInt(42);
176
buffer.writeLong(123456789L);
177
buffer.writeString("Hello, Fury!");
178
179
// Read back values (reset reader index first)
180
buffer.readerIndex(0);
181
int intValue = buffer.readInt();
182
long longValue = buffer.readLong();
183
String stringValue = buffer.readString();
184
```
185
186
### Working with Byte Arrays
187
188
```java
189
// Write byte arrays
190
byte[] data = {1, 2, 3, 4, 5};
191
buffer.writeBytes(data);
192
193
// Write partial array
194
buffer.writeBytes(data, 1, 3); // Write bytes at indices 1, 2, 3
195
196
// Read byte arrays
197
buffer.readerIndex(0);
198
byte[] readData = buffer.readBytes(5);
199
200
// Read into existing array
201
byte[] targetArray = new byte[3];
202
buffer.readBytes(targetArray, 0, 3);
203
```
204
205
### Direct Memory Buffers
206
207
```java
208
// Create direct (off-heap) buffer for large data
209
MemoryBuffer directBuffer = MemoryBuffer.newDirectBuffer(1024 * 1024); // 1MB
210
211
// Use for large binary data to avoid GC pressure
212
directBuffer.writeBytes(largeBinaryData);
213
214
// Convert to ByteBuffer for NIO operations
215
ByteBuffer byteBuffer = directBuffer.asByteBuffer();
216
```
217
218
### Buffer Position Management
219
220
```java
221
// Track positions
222
int initialWriterPos = buffer.writerIndex();
223
buffer.writeInt(100);
224
buffer.writeInt(200);
225
int finalWriterPos = buffer.writerIndex();
226
227
// Reset to read from beginning
228
buffer.readerIndex(0);
229
int first = buffer.readInt();
230
int second = buffer.readInt();
231
232
// Jump to specific position
233
buffer.readerIndex(initialWriterPos);
234
```
235
236
### Memory-Efficient Operations
237
238
```java
239
// Reuse buffers to avoid allocation
240
MemoryBuffer reusableBuffer = MemoryBuffer.newHeapBuffer(1024);
241
242
for (Object obj : objectsToSerialize) {
243
reusableBuffer.clear(); // Reset for reuse
244
fury.serialize(reusableBuffer, obj);
245
246
// Process serialized data
247
byte[] serializedData = reusableBuffer.toByteArray();
248
// ... send over network, write to file, etc.
249
}
250
```
251
252
### Platform-Specific Optimizations
253
254
```java
255
import org.apache.fury.memory.Platform;
256
import org.apache.fury.memory.MemoryUtils;
257
258
// Check platform characteristics
259
if (MemoryUtils.isLittleEndian()) {
260
// Optimize for little-endian byte order
261
}
262
263
// Direct memory operations (advanced usage)
264
long address = MemoryUtils.allocateMemory(1024);
265
try {
266
Platform.putInt(address, 42);
267
int value = Platform.getInt(address);
268
} finally {
269
MemoryUtils.freeMemory(address);
270
}
271
```
272
273
### Integration with Serialization
274
275
```java
276
// Use buffer with Fury serialization
277
MemoryBuffer buffer = MemoryBuffer.newHeapBuffer(1024);
278
279
// Serialize object to buffer
280
fury.serialize(buffer, myObject);
281
282
// Get serialized bytes
283
byte[] serializedBytes = buffer.toByteArray();
284
285
// Create new buffer for deserialization
286
MemoryBuffer deserializeBuffer = MemoryBuffer.newHeapBuffer(serializedBytes.length);
287
deserializeBuffer.writeBytes(serializedBytes);
288
deserializeBuffer.readerIndex(0);
289
290
// Deserialize from buffer
291
Object restored = fury.deserialize(deserializeBuffer);
292
```
293
294
### Working with Large Datasets
295
296
```java
297
// Handle large datasets efficiently
298
public void processLargeDataset(List<LargeObject> dataset) {
299
// Use larger buffer for batch processing
300
MemoryBuffer batchBuffer = MemoryBuffer.newDirectBuffer(10 * 1024 * 1024); // 10MB
301
302
for (int i = 0; i < dataset.size(); i++) {
303
if (batchBuffer.remain() < ESTIMATED_OBJECT_SIZE) {
304
// Process current batch
305
processBatch(batchBuffer);
306
batchBuffer.clear();
307
}
308
309
fury.serialize(batchBuffer, dataset.get(i));
310
}
311
312
// Process remaining data
313
if (batchBuffer.writerIndex() > 0) {
314
processBatch(batchBuffer);
315
}
316
}
317
```
318
319
## Performance Considerations
320
321
### Buffer Selection
322
323
- **Heap Buffers**: Better for small-medium data sizes, easier GC management
324
- **Direct Buffers**: Better for large data, reduced GC pressure, but allocation overhead
325
- **Buffer Reuse**: Reuse buffers when possible to avoid allocation overhead
326
327
### Memory Access Patterns
328
329
- **Sequential Access**: Most efficient, leverages CPU cache
330
- **Aligned Access**: Better performance on some platforms
331
- **Batch Operations**: Use array operations when possible for better throughput
332
333
### Platform Optimizations
334
335
- **Endianness**: Fury automatically handles platform endianness
336
- **Unsafe Operations**: Used internally for maximum performance
337
- **Memory Alignment**: Considered for optimal memory access patterns
338
339
### Memory Management Best Practices
340
341
1. **Reuse Buffers**: Create buffer pools for frequently used buffer sizes
342
2. **Monitor Memory Usage**: Track direct memory usage to avoid OutOfMemoryError
343
3. **Choose Appropriate Buffer Size**: Balance between memory usage and allocation frequency
344
4. **Clean Up Direct Buffers**: Ensure proper cleanup of direct memory
345
5. **Use Appropriate Buffer Type**: Heap for small data, direct for large data or when interfacing with NIO