blob: ecb38646e3f55319584ad85531ae77fc22972d31 [file] [log] [blame]
/*
* 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.
*/
package org.apache.mnemonic.examples;
import java.nio.ByteBuffer;
import java.util.Random;
import org.apache.mnemonic.VolatileMemAllocator;
import org.apache.mnemonic.CommonAllocator;
import org.apache.mnemonic.MemBufferHolder;
import org.apache.mnemonic.MemChunkHolder;
import org.apache.mnemonic.MemClustering;
import org.apache.mnemonic.Reclaim;
import org.apache.mnemonic.SysMemAllocator;
import org.apache.mnemonic.Utils;
/**
* Main is the class of example.
*
*/
@SuppressWarnings("restriction")
public class Main {
/**
* Run a example code to demonstrate some basic functionalities.
*
* @param argv
* array of commandline parameters
*/
public static void main(String[] argv) throws Exception {
Random randomGenerator = new Random();
/* Generate configuration for each node */
/*
* Currently only one node is supported due to the external native code
* 'vmem' returns null for multiple 'vmem' allocator instantialization
*/
MemClustering.NodeConfig ncs[] = new MemClustering.NodeConfig[] {
new MemClustering.NodeConfig(new SysMemAllocator(1024 * 1024 * 20, true).disableActiveGC(),
MemClustering.PerformanceLevel.FASTEST),
// new MemClustering.NodeConfig(new
// BigDataMemAllocator(1024*1024*20, ".",
// true).disableActiveGC(),
// MemClustering.PerformanceLevel.FAST),
// new MemClustering.NodeConfig(new
// BigDataMemAllocator(1024*1024*20, ".",
// true).disableActiveGC(),
// MemClustering.PerformanceLevel.NORMAL),
new MemClustering.NodeConfig(
new VolatileMemAllocator(Utils.getVolatileMemoryAllocatorService("vmem"), 1024 * 1024 * 20, "."),
// 1024 * 1024 * 20, "./example.dat", true),
MemClustering.PerformanceLevel.SLOW), };
for (MemClustering.NodeConfig nc : ncs) {
/**
* set a reclaimer for memory buffers
*/
nc.getAllocator().setBufferReclaimer(new Reclaim<ByteBuffer>() {
@Override
public boolean reclaim(ByteBuffer mres, Long sz) {
System.out.println(String.format("Reclaim Memory Buffer: %X Size: %s", System.identityHashCode(mres),
null == sz ? "NULL" : sz.toString()));
return false;
}
});
/**
* set a reclaimer for memory chunks
*/
nc.getAllocator().setChunkReclaimer(new Reclaim<Long>() {
@Override
public boolean reclaim(Long mres, Long sz) {
System.out
.println(String.format("Reclaim Memory Chunk: %X Size: %s", mres, null == sz ? "NULL" : sz.toString()));
return false;
}
});
}
/* Deploy Memory Clustering */
MemClustering mclst = new MemClustering(ncs);
/**
* Set event callback for allocator changing. this callback is used to trace
* the event of spilling out of allocation when previous allocator is unable
* to meet the allocation requirement so trying to switch to next allocator.
*/
mclst.setAllocatorChange(new MemClustering.AllocatorChange() {
@Override
public void changed(MemClustering.PerformanceLevel lvl, CommonAllocator prevallocator,
CommonAllocator tgtallocator) {
System.out.println(String.format("AllocatorChanged: %s, %X -> %X", lvl.name(),
System.identityHashCode(prevallocator), System.identityHashCode(tgtallocator)));
}
});
/**
* Set event callback for performance level changing. this callback is used
* to trace the event of downgrading to low level performance allocation.
*/
mclst.setPerformanceLevelChange(new MemClustering.PerformanceLevelChange() {
@Override
public void changed(MemClustering.PerformanceLevel prevlvl, MemClustering.PerformanceLevel lvl) {
System.out.println(
String.format("PerfLevelChanged: %s -> %s", null == prevlvl ? "NULL" : prevlvl.name(), lvl.name()));
}
});
/**
* Start to create a piece of memory resource backed ByteBuffer and then
* automatically release it or manually release it every six objects.
*/
System.out.println(Utils.ANSI_GREEN + "[[Demo Allocation, Auto Destruction "
+ "and Manual Destruction of Big Memory ByteBuffer.]]" + Utils.ANSI_RESET);
MemBufferHolder<?> mbh;
for (int idx = 1; idx <= 50; ++idx) {
int size = randomGenerator.nextInt(1024 * 1024) + 1024 * 1024;
mbh = mclst.createBuffer(size);
if (null == mbh) {
throw new OutOfMemoryError("Memory Cluster out of memory!");
}
for (int i = 0; i < size; i++) {
/**
* Manipulate the ByteBuffer backed by external memory resource. Note:
* Do not assigned internal ByteBuffer object to any variable, only use
* function get() to access it all time.
*/
mbh.get().put((byte) randomGenerator.nextInt(255));
}
System.out.println(String.format("[Seq.%d] size %d - %d, (%s)", idx, size, mbh.get().capacity(),
size == mbh.get().capacity() ? "Correct" : "Failed!!!"));
if (idx % 6 == 0) {
/**
* Force to release memory resource of specified ByteBuffer object
* immediately.
*/
System.out.println(String.format("Manually destroy Buffer at %X.", System.identityHashCode(mbh.get())));
mbh.destroy();
}
System.out.println("-------------------");
}
// Utils.collectGarbage();
/**
* Start to create a piece of memory resource backed chunk and then
* automatically release it or manually release it every six chunks.
*/
System.out.println(Utils.ANSI_GREEN + "[[Demo Allocation, Auto Destruction "
+ "and Manual Destruction of Big Memory Chunk.]]" + Utils.ANSI_RESET);
@SuppressWarnings({"restriction", "UseOfSunClasses"})
sun.misc.Unsafe unsafe = Utils.getUnsafe();
MemChunkHolder<?> mch;
for (int idx = 1; idx <= 50; ++idx) {
int size = randomGenerator.nextInt(1024 * 1024) + 1024 * 1024;
mch = mclst.createChunk(size);
if (null == mch) {
throw new OutOfMemoryError("Memory Cluster out of memory!");
}
// mch.cancelAutoReclaim();
mch.resize(size - 10);
System.out.printf("chunk size is %d \n", mch.getSize());
for (int i = 0; i < mch.getSize(); i++) {
/**
* Manipulate the chunk data. Note: Do not assigned the internal memory
* space to any variable, please always use function get() to access it
* at all time.
*/
unsafe.putByte(mch.get() + i, (byte) randomGenerator.nextInt(255));
}
System.out.println(String.format("[Seq.%d] size %d - %d at %X.", idx, size, mch.getSize(), mch.get()));
if (idx % 6 == 0) {
/**
* Force to release memory resource of specified Chunk object
* Immediately.
*/
System.out.println(String.format("Manually destroy Chunk at %X.", mch.get()));
mch.destroy();
}
System.out.println("-------------------");
}
}
}