为避免GC的负效应, 使用DirectByteBuffer管理原始(Raw)数据会为高负载的系统带来性能的提升. DirectByteBuffer默认是由GC来回收的, 这通常能够满足需求, 若要想自己控制回收的时机, 可以使用这段代码.
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
* {@link DirectByteBufferCleaner}
*
* @author <a href=mailto:zhong.lunfu@gmail.com>zhongl</a>
* @created 2011-1-14
*/
public final class DirectByteBufferCleaner {
private DirectByteBufferCleaner() {}
public static void clean(final ByteBuffer byteBuffer) {
if (!byteBuffer.isDirect()) return;
try {
Object cleaner = invoke(byteBuffer, "cleaner");
invoke(cleaner, "clean");
} catch (Exception e) { /* ignore */ }
}
private static Object invoke(final Object target, String methodName) throws Exception {
final Method method = target.getClass().getMethod(methodName);
return AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
try {
return method.invoke(target);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
}
}
分享到:
相关推荐
Java的普通ByteBuffer是基于堆内存的,它会创建一个对象并分配相应的内存空间,当数据量大时,频繁的内存分配和垃圾回收会带来额外的开销。而DirectByteBuffer则不同,它直接在物理内存中分配空间,绕过了Java对象的...
某些情况下,为了避免在关键操作期间进行垃圾回收,可以使用内存池或本地内存(如DirectByteBuffer)来减少垃圾回收的频率。 此外,Java允许在对象被回收前执行一些清理操作,这通常通过覆盖`finalize()`方法来实现...
《DirectByteBuffer2》是Java基础课程中的一个重要章节,主要探讨了Java内存管理中直接缓冲区的概念、使用及其优势。在Java编程中,内存管理对于性能优化至关重要,而直接缓冲区(Direct ByteBuffer)作为Java NIO...
- **堆外分配**:使用`DirectByteBuffer`或直接通过`Unsafe`类的`allocateMemory`方法,但这不推荐,因为可能引发内存泄漏。 4. **监控方法**: - `jstat -gcutil`:查看堆中各区域的变化及GC状态。 - `-XX:+...
- 通常用于管理堆外内存,如 DirectByteBuffer,当对象将被回收时,可以做一些额外的清理工作。 ThreadLocal 工作原理: - 每个 ThreadLocal 实例都有一个 ThreadLocalMap,它不是 HashMap 而是基于 Entry 实现的...
在`DirectByteBuffer`的案例中,`Cleaner`创建了一个`Deallocator`对象,这个`Runnable`在`run`方法中负责释放底层的本机内存。这种方式确保了即使对象被垃圾收集,相关的资源也会被正确地释放,而且不会阻塞垃圾...
**直接内存(Direct Memory)**:直接内存并不是在JVM规范中定义的内存区域,而是在`NIO`类中提供的`DirectByteBuffer`对象,可以直接访问内存地址,这使得某些数据的读写速度更快。由于直接内存不受Java堆大小的限制...
* 堆外分配:使用 DirectByteBuffer 或 Unsafe.allocateMemory 进行堆外分配,但不推荐这种方式。 4. 监控方法 JVM 提供了多种监控方法来查看内存区域的变化和 GC 的工作状态,包括: * `jstat –gcutil`:查看堆...
- `DirectByteBuffer` 直接分配堆外内存。 - `Unsafe.allocateMemory` 提供了一种不推荐的直接内存分配方式。 #### 五、内存回收 - **Hotspot 认为没有引用的对象是 dead 的**: - 通过可达性分析确定哪些对象...
DirectByteBuffer的创建过程相当复杂,涉及到内存分配、资源管理以及垃圾回收的协调。在分配堆外内存时,会通过`Bits.reserveMemory(size,cap)`方法进行检查和分配。这个方法会尝试确保有足够的堆外内存可供分配,...
栈分配适用于局部变量,而堆外分配主要用于DirectByteBuffer等特殊场景,但直接使用Unsafe类的allocateMemory并不推荐,因为它可能导致内存泄漏。 在内存回收过程中,Hotspot JVM根据引用的强度将其分为Strong、...
直接内存(堆外内存)用于存放不在JVM堆内的内存对象,由操作系统管理,通过DirectByteBuffer进行操作,避免了在Java堆和Native堆之间复制数据。 Java对象的创建过程首先检查常量池中是否存在该类的符号引用,并...
3. **内存管理**:分配成功后,`DirectByteBuffer`会维护一个引用到这块内存,但不参与JVM的垃圾回收机制。这意味着开发者需要手动管理这部分内存,否则可能导致内存泄露。 ### 4. 注意事项与优化 - **内存限制**...
JDK 1.4引入的NIO允许直接在堆外分配内存,通过DirectByteBuffer对象引用,减少了堆内存和堆外内存的数据拷贝,提高了性能。 总结来说,理解JVM的运行时数据区域、垃圾收集机制以及相关参数设置对于优化Java应用的...
- **直接内存**: 堆外内存,如NIO使用的DirectByteBuffer对象。 #### Eden与Survivor分区 在HotSpot JVM中,新生代进一步细分为一个Eden区和两个Survivor区(通常标记为From和To),默认比例为8:1。新创建的对象...
- **描述**:非JVM运行时数据区的部分,JDK1.4引入NIO,可直接分配堆外内存,通过DirectByteBuffer对象作为引用。使用本地函数库直接分配,避免了Java堆和Native堆之间的数据交换,提高IO读写性能。 - **异常**:...
直接内存的分配是通过sun.misc.Unsafe类(非公开API,但广泛用于高性能库中)或者Java NIO的DirectByteBuffer类实现的。这些类能够直接在操作系统堆外内存中申请空间,避免了JVM的内存分配和垃圾回收过程。然而,...
堆外内存主要用于存储NIO的DirectByteBuffer等对象,可以减少频繁的垃圾回收操作,提高程序性能。 ### 性能优化 #### 编译优化技术 JVM提供了多种编译优化技术来提升程序运行效率。例如,内联缓存、逃逸分析、锁...
2. OutOfMemoryError: GC overhead limit exceeded:超过 98% 的时间用来做 GC 并且回收了不到 2% 的堆内存。 3. OutOfMemoryError: Direct buffer memory:堆外内存。 4. OutOfMemoryError: unable to create new ...