Apache DirectMemory介绍

顾英发
2023-12-01

Apache DirectMemory 是一个多层的缓存系统,特性包括无堆的内存管理用于支持大规模的 Java 对象,而不会影响 JVM 垃圾收集器的性能。

官网:http://directmemory.apache.org/

项目:https://github.com/raffaeleguidi/DirectMemory

实例:

package cn.slimsmart.apache.directmemory;

import java.lang.reflect.Field;
import java.util.Date;

import org.apache.directmemory.DirectMemory;
import org.apache.directmemory.cache.Cache;

public class Test {

	public static void main(String[] args) throws Exception {
		/*
		 * numberOfBuffers 缓冲区数目
		 * size  缓存大小
		 * initialCapacity 初始容量
		 * concurrencyLevel 并发级别,guava new MapMaker().concurrencyLevel(4)
		 */
		Cache.init(10, 100, DirectMemory.DEFAULT_INITIAL_CAPACITY, DirectMemory.DEFAULT_CONCURRENCY_LEVEL);
		Cache.put("key1", "abc");
		Cache.put("key2", 123);
		Cache.put("key3", new Date());
		Cache.put("key4", "abc",1000);

		Class<?> c = Class.forName("java.nio.Bits");
		Field maxMemory = c.getDeclaredField("maxMemory");
		maxMemory.setAccessible(true);
		Field reservedMemory = c.getDeclaredField("reservedMemory");
		reservedMemory.setAccessible(true);
		Long maxMemoryValue = (Long) maxMemory.get(null);
		Long reservedMemoryValue = (Long) reservedMemory.get(null);
		System.out.println("maxMemoryValue:" + maxMemoryValue);
		System.out.println("reservedMemoryValue:" + reservedMemoryValue);
		
		System.out.println("key1="+Cache.retrieve("key1"));
		System.out.println("key2="+Cache.retrieve("key2"));
		System.out.println("key3="+Cache.retrieve("key3"));
		System.out.println("key4="+Cache.retrieve("key4"));
		
		Thread.sleep(1000);
		System.out.println("******************************************");
		System.out.println("key1="+Cache.retrieve("key1"));
		System.out.println("key4="+Cache.retrieve("key4"));
	}

}
添加依赖pom.xml
<!-- apache directmemory -->
		<dependency>
			<groupId>org.apache.directmemory</groupId>
			<artifactId>directmemory-cache</artifactId>
			<version>0.2</version>
		</dependency>
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.7.4</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.5</version>
		</dependency>
DirectMemory是java nio引入的,直接以native的方式分配内存,不受jvm管理。这种方式是为了提高网络和文件IO的效率,避免多余的内存拷贝而出现的。DirectMemory 的默认大小是64M,而JDK6之前和JDK6的某些版本的SUN JVM,存在一个BUG,在用-Xmx设定堆空间大小的时候,也设置了DirectMemory的大小。加入设置了-Xmx2048m,那么jvm最终可分配的内存大小为4G多一些,是预期的两倍。解决方式是设置jvm参数-XX:MaxDirectMemorySize=128m,指定DirectMemory的大小。DirectMemory占用的大小没有直接的工具或者API可以查看,不过这个在Bits类中是有两个字段存储了最大大小和已分配大小的。

存在的问题: 
Cache类是单例,在同一个JVM里,不能根据实际应用创建不同的Cache(可以实现自己的Cache);
OffHeapMemoryBuffer中ByteBuffer 空间存在浪费; 要根据业务类型,合理分配OffHeapMemoryBuffer的容量;
目前Map<key>还是存放在Heap里,只是Value存放在Off-Heap,不过可以根据需要修改代码

Direct-Memory依赖的其他类库 JoSQL SQL for Java Objects http://josql.sourceforge.net/,guava google-common-collection http://code.google.com/p/guava-libraries/其中的MapMaker的使用。

 类似资料: