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

为什么Ignite在网格激活时为JVM分配32GB的额外内部内存?

鞠通
2023-03-14

嗨,我们使用Apache Ignite2.7(8个节点,每个120GB)并配置16GB堆和100GB数据区域(持久化)。使用本机内存跟踪,我们可以看到通常预期的堆、线程等类别与预期的一样,但“内部”(即离堆)是惊人的132GB。这是JVM需要运行的最重要的东西。对于JVM如此巨大的内存请求,系统正被驱动到内存不足的情况(OS内存不足)。

下面是我们正在看到的一个典型的本地内存摘要。注意巨大的内部分配。

本机内存总量:Reserved=156688325KB,Committed=156439245KB-Java堆(Reserved=16777216KB,Committed=16777216KB)(MMAP:Reserved=16777216KB,Committed=16777216KB)-类(Reserved=112257KB,Committed=111489KB)(classes#17951)(Malloc=1665KB#17624)(MMAP:Reserved=110592KB,Committed=109824KB)-线程(Reserved=229015KB,堆栈:保留=228032KB,Committed=228032KB)(Malloc=723KB#1128)(arena=260KB#432)-代码(保留=255790KB,Committed=40250KB)(Malloc=6190KB#11547)(MMAP:保留=249600KB,Committed=34060KB)-GC(保留=704014KB,Committed=704014KB)(Malloc=48654KB#22251)(MMAP:保留=655360KB,Committed=655360KB)-编译器(保留=420KB,=420KB)(malloc=289KB#1284)(arena=131KB#15)-内部(reserved=138544815KB,committed=138544811KB)(malloc=138544779KB#35177)(MMAP:reserved=36KB,committed=32KB)-符号(reserved=26536KB,committed=26536KB)(malloc=24002KB#216741)(arena=2533KB#1)-本机内存TraCing(reserved=4822KB,committed=4822KB)(Malloc=30KB#346)(跟踪Overhead=4791KB)-竞技场块(reserved=673KB,committed=673KB)(Malloc=673KB)-未知(reserved=32768KB,committed=0KB)(MMAP:reserved=32768KB,committed=0KB)

PS

我们将默认数据区域设置为128MB,systemRegionMaxSize设置为8GB,systemRegionInitialSize设置为512MB。

配置:

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <property name="gridLogger">
      <bean class="org.apache.ignite.logger.log4j.Log4JLogger">
        <constructor-arg type="java.lang.String" value="/opt/ignite/apache-ignite/config/log4j.xml"/>
      </bean>
    </property>
    <property name="metricsLogFrequency" value="600000"/>
    <property name="rebalanceThreadPoolSize" value="12"/>
    <property name="peerClassLoadingEnabled" value="true"/>
    <property name="publicThreadPoolSize" value="32"/>
    <property name="systemThreadPoolSize" value="32"/>
    <property name="workDirectory" value="/data/ignite/work"/>
    <property name="segmentationPolicy" value="RESTART_JVM"/>
    <property name="dataStorageConfiguration">
      <bean class="org.apache.ignite.configuration.DataStorageConfiguration">
        <property name="checkpointReadLockTimeout" value="0"/>
        <property name="systemRegionInitialSize" value="#{512L * 1024 * 1024}"/>
        <property name="systemRegionMaxSize" value="#{8L * 1024 * 1024 * 1024}"/>
        <property name="storagePath" value="/data/ignite/persistentStore"/>
        <property name="defaultDataRegionConfiguration">
          <bean class="org.apache.ignite.configuration.DataRegionConfiguration">
            <property name="name" value="Default_Region"/>
            <property name="initialSize" value="67108864"/>
            <property name="maxSize" value="134217728"/>
            <property name="persistenceEnabled" value="false"/>
            <property name="metricsEnabled" value="true"/>
          </bean>
        </property>
        <property name="dataRegionConfigurations">
          <list>
            <bean class="org.apache.ignite.configuration.DataRegionConfiguration">
              <property name="name" value="Tiered_Region"/>
              <property name="initialSize" value="53687091200"/>
              <property name="maxSize" value="53687091200"/>
              <property name="persistenceEnabled" value="true"/>
              <property name="pageEvictionMode" value="RANDOM_2_LRU"/>
              <property name="evictionThreshold" value="0.75"/>
              <property name="metricsEnabled" value="true"/>
            </bean>
          </list>
        </property>
      </bean>
    </property>
    <property name="cacheConfiguration">
      <list>
        <bean class="org.apache.ignite.configuration.CacheConfiguration">
          <property name="name" value="default"/>
          <property name="atomicityMode" value="ATOMIC"/>
          <property name="backups" value="0"/>
        </bean>
      </list>
    </property>
    <property name="communicationSpi">
      <bean class="org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi">
        <property name="messageQueueLimit" value="#{1 * 1024}"/>
        <property name="idleConnectionTimeout" value="30000"/>
      </bean>
    </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.s3.TcpDiscoveryS3IpFinder">
            <property name="awsCredentials" ref="aws.creds"/>
            <property name="bucketName" value="project-test-xyz"/>
          </bean>
        </property>
      </bean>
    </property>
  </bean>
  <bean id="aws.creds" class="com.amazonaws.auth.BasicAWSCredentials">
    <constructor-arg value="foo"/>
    <constructor-arg value="bar"/>
  </bean>
</beans>

[在下面添加日志]

共有1个答案

窦宏旷
2023-03-14

我认为这是检查点页面缓冲区,默认情况下是数据区域大小的20%。

您可以显式地指定它以确保不会忘记它,并相应地减小区域大小以确保不会用完RAM。

应该只适用于持久区域。

注意,您还应该期望操作系统对其数据结构和块缓存占用一些GBs,所以我认为不应该将120G中的116G分配给Ignite的离堆。也别忘了堆。

 类似资料:
  • JVM选项: 正如预期的那样,JVM将为JVM堆分配将近20MB的内存。 但请参阅以下 GC 详细信息: PSYoungGen总计9216K,已用4612k[0x 00000000 ff 6000000,0x 0000000010000000100000000]< br > Eden空间8192K,56%已用[0x 000000000 ff 600000,0x 0000000 FFA 812d 8

  • 直到今天,我才知道java有堆,堆是由JVM创建的。此外,这个内存是由操作系统分配给JVM实例的,即堆驻留在JVM实例中。 这表明,JVM和堆相距甚远。 所以,我现在很困惑,有谁能让我知道,我以前是错的还是我不能理解这幅画?

  • 它应该取消比赛,这样同一队的球员就不能互相攻击,但事实并非如此。为什么?您还可以建议创建FriendlyFire函数的其他方法。

  • 我目前正试图了解x86_64上某些环路的性能属性(具体来说,我的Intel(R)Core(TM)i3-8145U CPU@2.10GHz处理器)。具体来说,在循环体中添加一条额外的指令来读取内存,几乎可以将性能提高一倍,而细节并不特别重要。 我一直在使用一个由两个主要部分组成的测试程序:一个测试循环和一个正在测试的函数。测试循环运行测试2下的函数32次,每次一个有符号32位整数作为参数(按INT\

  • 为什么我不能这样做/是否有解决方法来实现这一点: 这两个编译错误是 > On

  • 我的问题是,谁分配和管理这些内存段?操作系统不知道java程序正在运行,并认为它是JVM的一部分,作为计算机上的常规程序运行,JIT编译、java堆栈的使用,这些操作需要运行时内存分配,我不明白的是JVM如何将其内存划分为这些内存段。这肯定不是由操作系统来完成的,这些内存段(例如java堆栈)必须是连续的才能工作,所以如果JVM程序只是使用malloc命令来接收堆内存的最大大小并将这些内存划分为多