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

标签 java jvm heap-memory ignite

我正在尝试将 Ignite 用作内存数据库,用于存储值范围为 50MB 到 800MB 的键值对。看起来 Ignite 通过 JVM 分配堆空间,它永远不会清理,即使缓存条目不在堆中,被清除,没有连接的客户端,也没有运行的操作。我的机器无法处理这种内存消耗,因此我正在寻找一种清理内存的方法。

我的测试场景如下:

  • Ignite 2.9 版
  • 使用 OpenJDK 11 运行

我正在使用 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 左右:

Ignite heap

使用相同的数据执行第二次测试运行不会导致 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% 的 Activity 字节映射到 byte[]
  • 似乎有 client-connector 和 data-streamer-stripe 线程保持打开状态,缓存中的每个 put 操作一个,但我不确定它们需要多少堆
  • 在 my_cache.put 中提供值提示没有帮助
  • cache.clear()、cache.destroy() 没有帮助(它不应该,因为缓存在堆外)

非常感谢任何帮助!

最佳答案

  1. 默认情况下,Apache Ignite 不在堆上保存数据,而是在堆外保存数据。
  2. Apahce Ignite 确实不会在删除数据时释放堆外数据,但它允许在摄取新数据时重新使用所述堆外数据。
  3. 完全不清楚为什么您的工具会报告使用了 ~16G 堆,因为 Ignite 在提供的配置下不应使用超过几百 MB。如果那不仅是堆而且是所有 RAM,那么您就可以了。您应该期望分配 10G。为什么它在 Size 字段中报告更多尚不清楚。

关于java - Apache Ignite 中可能存在内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64550479/

相关文章:

linux - 内存:堆栈和交换

java - 使用 Java 构建 Maven : How to execute script located in resources?

Java 堆/池大小

java - Java如何调用对象的函数?

c++ - 访问静态和堆内存的速度

c++ - C++ 堆损坏检测工具

java - 如何改变HashSet中的值?

java - Firebase Valueeventlistener 花费了很多时间

java - 如何判断堆转储中字符串与 char[] 的比率是否表明存在问题?

Java:Java 是否在幕后将方法参数转换为数组?