Spring 弹簧批饱和存储器

Spring 弹簧批饱和存储器,spring,memory-leaks,out-of-memory,batch-processing,spring-batch,Spring,Memory Leaks,Out Of Memory,Batch Processing,Spring Batch,更新: 我尝试添加一些细节,因为解决这个问题对我来说非常重要 我做了一个批处理,从一些表中的数据生成pdf文档,并将pdf保存在一个表中。批处理还可以,但要处理的数据非常大,因此我决定将输入数据分成8组,并用8个并行步骤独立处理8组。 每个步骤都有自己的读卡器(步骤“X”的名称为“readerX”),并且具有与其他步骤相同的处理器和写入程序 精化进展顺利,但我的客户说该批处理使用了太多内存(他查看了perfmon中的“Working Set”参数)。特别是,批处理从300Mb已用内存开始,然后已

更新:

我尝试添加一些细节,因为解决这个问题对我来说非常重要

我做了一个批处理,从一些表中的数据生成pdf文档,并将pdf保存在一个表中。批处理还可以,但要处理的数据非常大,因此我决定将输入数据分成8组,并用8个并行步骤独立处理8组。 每个步骤都有自己的读卡器(步骤“X”的名称为“readerX”),并且具有与其他步骤相同的处理器和写入程序

精化进展顺利,但我的客户说该批处理使用了太多内存(他查看了perfmon中的“Working Set”参数)。特别是,批处理从300Mb已用内存开始,然后已用内存达到7GB,然后降至2GB,批处理以1/2GB已分配内存结束

我将作业的代码粘贴在这里,希望有人能帮助我找到问题(我想我在将作业调整为并行处理时犯了一些错误)

我是spring batch的新手,所以我为“糟糕的外观”道歉


//8个读者的情况不同
//8个读者的情况不同
[…]//其他bean

谢谢

如果您最终得到了OOM,请首先从堆开始

使用-XX:+HeapDumpOnOutOfMemoryError启动JVM以获取HPROF,然后可以查看该HPROF以查看对象分配、大小等。当JVM带OOM退出时,将生成此文件(可能需要一些时间,具体取决于大小)

如果您能够使用更大的内存足迹(如客户端计算机)运行,请在堆消耗大量内存(如您提到的7GB)时拍摄堆快照(或任何其他被认为高的值-4、5、6等)。您应该能够在通过JDK中的jconsole等工具运行时调用它


通过HPROF文件,您可以使用JDK提供的工具(如jhat)或基于GUI的工具(如eclipse内存分析器)检查该文件。这将为您提供一种很好(且相对简单)的方法,找出哪些内容保留了哪些内容,并为减少占用空间提供一个起点。

使用探查器和优化代码,我成功地限制了内存消耗。谢谢大家

批处理还可以,但要处理的数据非常大,因此我决定将输入数据分成8组,并用8个并行步骤独立处理8组


如果在同一台机器上并行处理,则不会减少内存足迹。所有数据同时存在于内存中。如果要减少内存使用,您必须依次执行这些步骤。

是否会在我的电脑中获得标记的内存不足?是,在客户端服务器上否。。但是7GB对我的客户来说太多了。你能提供一些关于错误的见解吗?例外?线程转储?该配置在无数的生产环境中使用,没有任何问题,因此我们需要更多的操作。我在服务器上没有例外,批处理成功执行。问题是,客户端正在使用perfmon监视我的批处理,并说工作集的内存达到7GB。。。太多了,这里的信息太少了。我们需要一些代码、线程转储等,否则将无法为您提供帮助。这种异常内存消耗的原因是什么?与数据库的连接配置不正确。。。我不知道为什么问题解决后。。。
<job id="myJob"
    xmlns="http://www.springframework.org/schema/batch">
    <step id="step1" next="step2">
        <tasklet ref="task1" />
    </step>
    <step id="step2" next="step3">
        <tasklet ref="task2" />
    </step>
    <step id="step3" next="decider">
        <tasklet ref="task3" />
    </step>
    <decision id="decider" decider="StepExecutionDecider">
        <next on="CASE X"   to="split1" />
        <end on="*"/>   
    </decision>
    <split id="split1" task-executor="taskExecutor" next="endStep">
        <flow>
            <step id="EXEC1">
                <tasklet><chunk reader="reader1" processor="processor" writer="writer" commit-interval="100"/>
                <listeners>
                    <listener ref="Listner" />
                </listeners>
                </tasklet>
            </step>
        </flow>
        <flow>
            <step id="EXEC2">
                <tasklet><chunk reader="reader2" processor="processor" writer="writer" commit-interval="100"/>
                <listeners>
                    <listener ref="Listner" />
                </listeners>
                </tasklet>
            </step>
        </flow>
        <flow>
            <step id="EXEC3">
                <tasklet><chunk reader="reader3" processor="processor" writer="writer" commit-interval="100"/>
                <listeners>
                    <listener ref="Listner" />
                </listeners>

                </tasklet>
            </step>
        </flow>
         <flow>
            <step id="EXEC4">
                <tasklet><chunk reader="reader4" processor="processor" writer="writer" commit-interval="100"/>
                <listeners>
                    <listener ref="Listner" />
                </listeners>

                </tasklet>
            </step>
        </flow>
         <flow>
            <step id="EXEC5">
                <tasklet><chunk reader="reader5" processor="processor" writer="writer" commit-interval="100"/>
                <listeners>
                    <listener ref="Listner" />
                </listeners>
                </tasklet>
            </step>
        </flow>
         <flow>
            <step id="EXEC6">
                <tasklet><chunk reader="reader6" processor="processor" writer="writer" commit-interval="100"/>
                <listeners>
                    <listener ref="Listner" />
                </listeners>

                </tasklet>
            </step>
        </flow>
         <flow>
            <step id="EXEC7">
                <tasklet><chunk reader="reader7" processor="processor" writer="writer" commit-interval="100"/>
                <listeners>
                    <listener ref="Listner" />
                </listeners>
                </tasklet>
            </step>
        </flow>
         <flow>
            <step id="EXEC8">
                <tasklet><chunk reader="reader8" processor="processor" writer="writer" commit-interval="100"/>              
                <listeners>
                    <listener ref="Listner" />
                </listeners>
                </tasklet>
            </step>
        </flow>
    </split>
    <step id="endStep" next="decider">
        <tasklet ref="task4" >
            <listeners>
                <listener ref="Listner" />
            </listeners>
        </tasklet>
    </step>
</job>

<bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor"/>

<bean id="reader1" class="class of the reader">
    <property name="idReader" value="1"/>   // Different for the 8 readers 
    <property name="subSet" value="10"/>    // Different for the 8 readers 
    <property name="dao" ref="Dao" />
    <property name="bean" ref="Bean" /> 
    [...] // Other beans
</bean>