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

Apache Ignite中可能存在内存泄漏?

澹台俊达
2023-03-14

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

我的测试场景如下:

    null

我正在使用pyignite瘦客户机,通过python脚本在本地测试Ignite:

client = Client()
client.connect('localhost', 10800)

my_cache = client.get_or_create_cache('default')
my_cache.clear()

data = createData() #creates 800 000 000 bytes test data

def put(caches):
  i = caches
  while i > 0:
    my_cache.put('my key' + str(i), data)
    i -= 1

put(5)

my_cache.remove_all()
my_cache.destroy()
client.close()

该脚本将800 MB的数据顺序写入5个不同的缓存项中。下面的快照说明了Ignite的堆是如何增长到峰值的,这本身是可以理解的,但之后即使在执行GC之后,堆也会保持在10GB左右:

点火堆

使用相同的数据执行第二次测试运行不会在GC之后导致更大的堆消耗,这使我相信Ignite在内部为传入数据分配缓冲区,这些缓冲区与数据的大小相对应。这个内存消耗太大了,从长远来看,我的机器将无法处理它。

ignite配置非常简单:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
        
        <!-- Durable memory configuration. -->
        <property name="dataStorageConfiguration">
            <bean class="org.apache.ignite.configuration.DataStorageConfiguration">
            <property name="dataRegionConfigurations">
                <list>
                <bean class="org.apache.ignite.configuration.DataRegionConfiguration">
                    <!-- Custom region name. -->
                    <property name="name" value="10GB_Region"/>
                    <!-- 100 MB initial size. -->
                    <property name="initialSize" value="#{100L * 1024 * 1024}"/>
                    <!-- 10GB maximum size. -->
                    <property name="maxSize" value="#{10096L * 1024 * 1024}"/>
                </bean>
                
                </list>
            </property>
                <!-- Redefining the default region's settings -->
                <property name="defaultDataRegionConfiguration">
                    <bean class="org.apache.ignite.configuration.DataRegionConfiguration">
                        <property name="name" value="Default_Region"/>
                        <property name="maxSize" value="#{5L * 1024 * 1024 * 1024}"/>
                    </bean>
                </property>
            </bean>
        </property>



        <property name="cacheConfiguration">
            <list>
                <!-- Partitioned cache example configuration (Atomic mode). -->
                <bean class="org.apache.ignite.configuration.CacheConfiguration">
                    <property name="name" value="default"/>
                    <property name="atomicityMode" value="ATOMIC"/>
                    <property name="backups" value="1"/>
                    <property name="dataRegionName" value="10GB_Region"/>
                </bean>
            </list>
        </property>

        <property name="discoverySpi">
            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                <property name="ipFinder">
                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
                        <property name="addresses">
                            <list>
                                <value>127.0.0.1:47500..47509</value>
                            </list>
                        </property>
                    </bean>

                </property>
            </bean>
        </property>
    </bean>
</beans>
  • Ignite visor明确表示缓存处于堆外
  • VisualVM直方图显示98%的活字节映射到byte[]
  • 似乎有客户端连接器线程和数据流带线程仍然处于打开状态,缓存中每个put操作都有一个线程,但我不确定它们需要多少堆
  • 在my_cache.put中提供值提示没有帮助
  • cache.clear()、cache.destroy()没有帮助(而且应该没有帮助,因为缓存在堆外)

任何帮助都将非常感谢!

共有1个答案

邓英卓
2023-03-14
  1. Apache Ignite默认情况下不在堆中保存数据,而是在堆外保存数据。
  2. APAHCE Ignite在删除数据时确实不会释放off-heap,但它允许在接收新数据时重新使用所述off-heap。
  3. 根本不清楚为什么您的工具会报告使用~16G堆,因为在提供的配置中,Ignite使用的MB不应该超过几百个。如果这不仅仅是堆,而是所有的内存,那么你就可以了。您应该预计应该分配10G。不清楚为什么它在大小字段中报告更多。
 类似资料:
  • 我正在启用持久性的Kubernetes集群中运行Ignite。每台机器都有一个24GB的Java堆,20GB专用于持久内存,内存限制为110GB。我的相关JVM选项是。在每个节点上运行DataStreamer数小时后,我的集群上的节点达到了它们的k8s内存限制,触发了OOM杀机。运行Java NMT后,我惊讶地发现分配给内部内存的空间数量巨大。 Kubernetes metrics证实了这一点:

  • 我正在编写一个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