我是靠谱客的博主 单薄百合,最近开发中收集的这篇文章主要介绍android 堆外内存,cassandra 堆外内存管理,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

为什么需要堆外内存呢

单有一些大内存对象的时候,JVM进行垃圾回收时需要收集所有的这些对象的内存也。增加了GC压力。因此需要使用堆外内存。

java 分配堆外内存

org.apache.cassandra.utils.memory.BufferPool也有相应的实现方法

private static ByteBuffer allocate(int size, boolean onHeap)

{

return onHeap

? ByteBuffer.allocate(size)

: ByteBuffer.allocateDirect(size);

}

ByteBuffer.allocate: 分配的是JVM内存,这个还是会被JVM回收

ByteBuffer.allocateDirect() 分配OS本地内存,调用的是操作系统的 unsafe.allocateMemory(size);方法分配内存

unsafe.setMemory(base, size, (byte) 0);内存的起始地址和大小存储在java.nio.DirectByteBuffer对象里。只有DirectByteBuffer对象被回收掉,内存才有可能被回收掉。

内存回收

当没有更多的堆外内存(-XX:MaxDirectMemorySize)的时候,就会触发一次Full-GC.

Cassandra 堆外内存管理

java 提供的堆外内存实现方便,但是有一定缺陷。因为堆外内存是全局的同步锁链表。当多个线程同时检测到堆外内存不够,就会相继的触发full-gc

cassandra中的rowcache是在堆外内存中。

org.apache.cassandra.service.CacheService.initRowCache()

// 调用了OHCProvider方法来实现

// cache object

ICache rc = cacheProvider.create();

AutoSavingCache rowCache = new AutoSavingCache<>(rc, CacheType.ROW_CACHE, new RowCacheSerializer());

int rowCacheKeysToSave = DatabaseDescriptor.getRowCacheKeysToSave();

rowCache.scheduleSaving(DatabaseDescriptor.getRowCacheSavePeriod(), rowCacheKeysToSave);

org.apache.cassandra.cache.OHCProvider

OHC 就是off-heap-cache

public ICache create()

{

OHCacheBuilder builder = OHCacheBuilder.newBuilder();

// 1.创建rowcache 内存空间

builder.capacity(DatabaseDescriptor.getRowCacheSizeInMB() * 1024 * 1024)

.keySerializer(KeySerializer.instance)

.valueSerializer(ValueSerializer.instance)

.throwOOME(true);

return new OHCacheAdapter(builder.build());

}

注1处是调用了ohc-core.jar中OHCacheBuilder来实现堆外内存分配

https://issues.apache.org/jira/browse/CASSANDRA-7438。cassandra目前也将这块的实现抽象出来了,作为一个独立的包,其他的应用也可以调用。

参考

最后

以上就是单薄百合为你收集整理的android 堆外内存,cassandra 堆外内存管理的全部内容,希望文章能够帮你解决android 堆外内存,cassandra 堆外内存管理所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(62)

评论列表共有 0 条评论

立即
投稿
返回
顶部