当前位置: 首页 > 知识库问答 >
问题:

Ignite DataStreamer中可能存在内存泄漏

何星鹏
2023-03-14

我正在启用持久性的Kubernetes集群中运行Ignite。每台机器都有一个24GB的Java堆,20GB专用于持久内存,内存限制为110GB。我的相关JVM选项是-xx:+alwayspretouch-xx:+useg1gc-xx:+scavengeBeforefullgc。在每个节点上运行DataStreamer数小时后,我的集群上的节点达到了它们的k8s内存限制,触发了OOM杀机。运行Java NMT后,我惊讶地发现分配给内部内存的空间数量巨大。

Java Heap (reserved=25165824KB, committed=25165824KB)
(mmap: reserved=25165824KB, committed=25165824KB)  

Internal (reserved=42425986KB, committed=42425986KB)
(malloc=42425954KB #614365) 
(mmap: reserved=32KB, committed=32KB) 

Kubernetes metrics证实了这一点:

“点燃缓存”是内核页面缓存。最后一个面板“heap+durabiled+buffer”是ignite指标heapmemoryused+physicalmemorysize+checkpointbuffersize的总和。

    <property name="dataStorageConfiguration">
        <bean class="org.apache.ignite.configuration.DataStorageConfiguration">
            <property name="metricsEnabled" value="true"/>
            <property name="checkpointFrequency" value="300000"/>
            <property name="storagePath" value="/var/lib/ignite/data/db"/>
            <property name="walFlushFrequency" value="10000"/>
            <property name="walMode" value="LOG_ONLY"/>
            <property name="walPath" value="/var/lib/ignite/data/wal"/>
            <property name="walArchivePath" value="/var/lib/ignite/data/wal/archive"/>               
            <property name="walSegmentSize" value="2147483647"/>
            <property name="maxWalArchiveSize" value="4294967294"/>
            <property name="walCompactionEnabled" value="false"/>
            <property name="writeThrottlingEnabled" value="False"/>
            <property name="pageSize" value="4096"/>                
            <property name="defaultDataRegionConfiguration">
                <bean class="org.apache.ignite.configuration.DataRegionConfiguration">
                    <property name="persistenceEnabled" value="true"/>
                    <property name="checkpointPageBufferSize" value="2147483648"/>
                    <property name="name" value="Default_Region"/>
                    <property name="maxSize" value="21474836480"/>
                    <property name="metricsEnabled" value="true"/>
                </bean>
            </property>
        </bean>
    </property> 

更新:当我禁用持久性时,内部内存将被正确处理:

更新:这里用一个可复制的例子来演示这个问题。它可以在docker至少有22GB内存和50GB存储空间的机器上运行。有趣的是,只有在将字节数组或字符串作为值传入时,泄漏才会真正明显。

共有1个答案

易扬
2023-03-14

设置WalSegmentSize=64MB(或仅删除设置并使用默认值)并设置-xx:MaxDirectMemorySize=

在计算Ignite的内存需求时,人们经常忘记的一件事是直接内存缓冲区大小。

直接内存缓冲区是从Java进程中的一个单独空间分配的由JVM管理的缓冲区--它既不是Java堆、点燃数据区域,也不是点燃检查点缓冲区。

这就解释了40GB的内部JVM内存(我认为那是数据区域+direct)。这也解释了为什么在持久性关闭时看不到问题--在这种情况下没有WAL。

>

  • 选择正常的WalSegmentSize。我不知道选择2GB的原因,但如果您确定有小WAL段的问题,我建议选择默认的64MB或256MB。

    通过-xx:maxdirectmemorysize= 对JVM的直接内存池设置限制。我发现将其设置为WalSegmentSize*4值是一个安全的选择,即在256MB-1GB范围内的某个地方。

  •  类似资料:
    • 我试图将Ignite用作键值对的内存数据库,其值范围从50MB到800MB不等。看起来Ignite通过JVM分配堆空间,它从不清理,即使缓存条目离开堆,被清除,没有连接的客户机和运行的操作。我的机器将无法处理这样的内存消耗,因此我正在寻找一种方法来清理一些内存。 我的测试场景如下: null 我正在使用pyignite瘦客户机,通过python脚本在本地测试Ignite: 该脚本将800 MB的数

    • 我正在编写一个spring boot 2应用程序,我正在使用SQL批量复制功能在SQL Server2012数据库中插入几条记录。每插入700行,我就有600 MB的泄漏 我已经试用了Microsoft驱动程序版本6.4.0.jre8和7.2.2.jre8,但任何东西都改变了。我尝试为tomcat更改Hikari连接池,但结果是一样的。 为了调用Microsoft API,我使用了包装器框架(ht

    • 问题内容: 我配置了tomcat以使用其他外部开源。 但是,在tomcat运行几分钟后,我得到: 是什么原因造成的? 我要去哪里看?可能是Tomcat上的数据池吗? Tomcat中的线程是什么意思? 已编辑 这是我的全部踪迹。该应用程序似乎在仍在运行时会重新加载其上下文-我不知道为什么! 问题答案: 消息实际上很清楚:某些东西创建了一个类型为type的值-这是一个很好的提示。这很可能意味着框架本身

    • 问题内容: 我收到以下警告: 我在server.js中编写了这样的代码: 如何解决呢? 问题答案: 这是在解释节点eventEmitter文档 这是哪个版本的Node?您还有什么其他代码?那不是正常行为。 简而言之,其:

    • 今天给大家聊聊咱们平时写代码的时候,最常见的String字符串代码,它的一些底层原理,以及使用不当可能引发的内存泄漏的问题,相信对于大家平时日常开发写代码会有一定的帮助。 String字符串在内存里是如何存储的? 首先呢,当我们平时在代码中写下一行String类型的代码时,大家知道这个String字符串在内存里是如何存储的吗?比如这样的一行代码:String username = “zhangsa

    • 也许我不知道如何正确地将领域与可观察对象一起使用,但当我从一个领域创建一个可观察对象并订阅它时,我似乎遇到了领域内存泄漏。我在onDestroy()中关闭领域,并在onPause()中取消订阅可观察的领域。但是,如果我添加并返回以下片段几次(它被添加到backbackback,并在背压时删除): 我注意到,如果我在Android studio中进行几次GC,然后进行堆转储,则会有多个Realm和R