OHC堆外内存

JVM内存模型

先复习一波JVM的内存模型,线程共享的区域为堆、方法区|永久代,线程不共享的区域为栈、程序计数器。

对象创建的整体流程可以用一图描述

image.png

内存逃逸
  1. 逃逸分析是指分析指针动态范围的方法,它同编译器优化原理的指针分析和外形分析相关联。
  2. 当变量(或者对象)在方法中分配后,其指针有可能被返回或者被全局引用,这样就会被其他方法或者线程所引用,这种现象称作指针(或者引用)的逃逸(Escape)。
  3. 通俗点讲,如果一个对象的指针被多个方法或者线程引用时,那么我们就称这个对象的指针发生了逃逸
  4. 逃逸分析的好处
    1. 栈上分配,可以降低垃圾收集器运行的频率。
    2. 同步消除,如果发现某个对象只能从一个线程可访问,那么在这个对象上的操作可以不需要同步。
    3. 标量替换,把对象分解成一个个基本类型,并且内存分配不再是分配在堆上,而是分配在栈上。这样的好处有,一、减少内存使用,因为不用生成对象头。二、程序内存回收效率高,并且GC频率也会减少

TLAB
  1. 每个线程在Java堆中预先分配一小块内存,然后再给对象分配内存的时候,直接在自己这块”私有”内存中分配,当这部分区域用完之后,再分配新的”私有”内存。
  2. TLAB是虚拟机在堆内存的eden划分出来的一块专用空间,是线程专属的。在虚拟机的TLAB功能启动的情况下,在线程初始化时,虚拟机会为每个线程分配一块TLAB空间,只给当前线程使用,这样每个线程都单独拥有一个空间,如果需要分配内存,就在自己的空间上分配,这样就不存在竞争的情况,可以大大提升分配效率。
  3. TLAB是堆内存的一部分,他在读取上确实是线程共享的,但是在内存分分配上,是线程独享的。

排除内存逃逸外,创建的对象都存放在堆内,使用堆内空间就要受制于JVM垃圾回收的管控,稍有不慎就会oom。

假如系统里就是需要大量本地数据缓存如何避免oom呢。

堆外内存

了解netty的朋友肯定熟悉这个概念,堆外缓存顾名思义不存放在堆中,摆脱JVM管控就不会收到gc的影响。

OHC

市场上成熟且高性能的当属开源堆外缓存组件OHC了。OHC全称为off-heap-cache,即堆外缓存,是2015年针对ApacheCassandra开发的缓存框架,后来从 Cassandra 项目中独立出来,成为单独的类库,其项目地址为

https://github.com/snazy/ohc 

特性

  1. 数据存储在堆外,只有少量元数据存储堆内,不影响 GC
  2. 支持为每个缓存项设置过期时间
  3. 支持配置 LRU、W_TinyLFU 驱逐策略
  4. 能够维护大量的缓存条目
  5. 支持异步加载缓存
  6. 读写速度在微秒级别

如何使用

// 序列化方式需要使用者手动实现 
OHCache<String, String> ohCache = OHCacheBuilder.<String, String>newBuilder()
                .keySerializer(new StringSerializer())
                .valueSerializer(new StringSerializer())
                .eviction(Eviction.LRU)
                .build();

ohCache.put("hello", "world");

image.png

  • 19
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值