xianyuya
V2EX  ›  Java

能否在 JVM 堆中开辟一块空间由自己控制不参与 JVM 的 GC

  •  
  •   xianyuya · Dec 31, 2020 · 4100 views
    This topic created in 2134 days ago, the information mentioned may be changed or developed.
    应用中有大量常驻老年代的对象(例如本地缓存),每次进行替换的时候大概率引起 cms gc,从而导致 rt 抖动,已知这部分对象是一定会进老年代的,并且替换频率很低,基本上一天一次,那么有没有可能在堆里面开辟一块空间专门来存放这部分数据,这部分空间中的对象的更新和删除都由应用代码控制,不参与 GC,这样既能减少 cms gc 次数和频率,又因为数据本身还是放在堆中的,无需再进行序列化,同放在堆外相比内存占用和性能都会比较好
    19 replies  •  2021-01-22 12:17:28 +08:00
    DeathBless
    DeathBless
    Dec 31, 2020
    1
    把比例调一下不是更方便
    除非你用堆外内存 不然不可能吧
    micean
    micean
    Dec 31, 2020
    2
    像 netty 这种有玩堆外内存的,堆内的就不了解了
    嫌本地缓存占用空间大,为什么不把缓存交给 redis 之类的应用?
    YouLMAO
    YouLMAO
    Dec 31, 2020
    3
    堆里面?你啥意思?颠覆 jvm 概率么
    native 或者叫 off heap,

    代码
    java.nio.DirectByteBuffer
    unsafe.allocateMemory
    JQD6r41PkI4o2mEz
    JQD6r41PkI4o2mEz
    Dec 31, 2020 via Android
    4
    Ehcache 了解下?
    YouLMAO
    YouLMAO
    Dec 31, 2020
    5
    @YouLMAO 颠覆 java 概念
    MeteorCat
    MeteorCat
    Dec 31, 2020 via Android
    6
    JNI 这样的吗?
    gabon
    gabon
    Dec 31, 2020 via Android
    7
    前两天刚看到一个开源软件在堆开辟空间自己管理,现在怎么也想不起来了,好难受
    littlewing
    littlewing
    Dec 31, 2020
    8
    自己管理内存堆外就行了,为啥非得在堆内
    gabon
    gabon
    Dec 31, 2020 via Android
    9
    got it 。Flink 解决内存问题的核心思想类似于 Spark 的 Project Tungsten 和 HBase 的 BlockCache:在 JVM 堆内或堆外实现显式的内存管理,即用自定义内存池来进行内存块的分配和回收,并将对象序列化后存储到内存块。因为内存可以被精准地申请和释放,而且序列化的数据占用的空间可以被精确计算,所以组件可以对内存有更好的掌控,这种内存管理方式也被认为是相比 Java 更像 C 语言化的做法。

    Flink 将 TaskManager 的运行时 JVM heap 分为 Network Buffers 、MemoryManager 和 Free 三个区域,如下图所示:
    gabon
    gabon
    Dec 31, 2020 via Android
    10
    http://tang.love/2019/04/21/overview_of_flink/
    wysnylc
    wysnylc
    Dec 31, 2020 via Android
    11
    堆内应该不行,堆外可以如 netty
    堆内不行的原因是 gc 没有白名单类似的策略
    YouLMAO
    YouLMAO
    Dec 31, 2020 via Android
    12
    @gabon 没鸟用的,flink 是用二进制数据放在老年代避免 gc 的,贴主说他不想反序列化,要对象,这样的唯一出路就是加入 Amazon 团队,他们在造一个新 Jvm,拥有自主知识产权
    mind3x
    mind3x
    Dec 31, 2020
    13
    成熟方案很多,例如好用的 http://www.mapdb.org/
    另外 JDK 14/15 也已经在标准化中了: https://openjdk.java.net/jeps/393
    mind3x
    mind3x
    Dec 31, 2020
    14
    @mind3x 呃,没注意是问在 JVM 堆里分配,那就不相关了。
    DoctorCat
    DoctorCat
    Dec 31, 2020
    15
    不是不行,但怎么判断你这策略是最佳实践? 或者把 gc 换成 G1 试试
    DoctorCat
    DoctorCat
    Dec 31, 2020
    16
    把 CMS 换成 G1 试试
    xianyuya
    xianyuya
    OP
    Jan 4, 2021
    17
    大家说的堆外其实有想过,也有一部分数据是采用 mmap 的方式读取的,不过放在堆外的数据,反序列化到堆内创建对象的时候就会有额外的内存开销。
    其实我最原始的问题是有一份一天一更新的只读数据( 1g 左右,因为性能问题所以需要放在内存中),要怎么处理才能尽可能在尽可能少占用内存的情况下,每天替换数据时不引起 stw,不对正在提供服务的 rpc 线程产生影响
    Joker123456789
    Joker123456789
    Jan 5, 2021
    18
    static Map ;

    单例类;

    都可以实现这个需求吧
    sueking
    sueking
    Jan 22, 2021
    19
    阿里自定义 JDK 实现了 叫 GCIH
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2157 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 80ms · UTC 16:03 · PVG 00:03 · LAX 08:03 · JFK 11:03
    ♥ Do have faith in what you're doing.