2

I am using Spring Integration for FTP/File poller. FTp/File poller polls every 5sec.

When i analyze the heap memory i can see ErrorHandlingTaskExecutor$1 filling up the heap memory.How to solve this issue.Below the code

   <!-- Default Poller --> 
<int:poller id="csvPoller" fixed-rate="${csv.poll.timeinterval}" max-messages-per-poll="3" default="true" error-channel="csvErrorChannel"/> 

<!-- ToDO Include Header TimeStamp+ corilation id? in the File Name -->
<int-ftp:inbound-channel-adapter id="csvFtpInbound"
            channel="csvFtpChannel"
            session-factory="ftpClientFactory"
            auto-create-local-directory="true"
            delete-remote-files="true"
            remote-directory="/"  
            local-filename-generator-expression="new java.text.SimpleDateFormat('yyyy-MM-dd-hhmmssSSS').format(new java.util.Date()) + '.'+ #this"  
            local-directory="${ftp.sync.folder}"
            remote-file-separator="/"
            filename-regex="[\s\S]*(\.txt|\.csv)">
</int-ftp:inbound-channel-adapter>
<!-- Re Try For the failed filed Polled? - -->

<int:channel id="csvFtpChannel" >
    <int:queue />
</int:channel>

<int-file:outbound-channel-adapter id="procesingFolderAdapter" channel="csvFtpChannel" delete-source-files="true" directory="${csv.processing.folder}"/>

<int-file:inbound-channel-adapter id="fileInBound" 
            channel="csvFileProcessingChannel"
            directory="${csv.processing.folder}" 
            prevent-duplicates="true"
            filename-regex="[\s\S]*(\.txt|\.csv)">
</int-file:inbound-channel-adapter>

<int:channel id="csvFileProcessingChannel" datatype="java.io.File" >
    <int:interceptors>
        <bean class="com.ws.interceptor.CSVFileAndSecurityValidationInterceptor"></bean>
    </int:interceptors> 
</int:channel>

<int:transformer id="csvTransformer" input-channel="csvFileProcessingChannel" output-channel="csvTransformedChannel" ref="csvTransformerBean"/>

 <bean id="csvTransformerBean" class="com.ws.transformer.CSVTransformer"></bean>  

<!-- Transformed Data Channel-->
<int:channel id="csvTransformedChannel">
</int:channel>

<!-- Routing to the CommonMessageRouter from here it routes to the Correct EndPoints i.e Service-activator -->
<int:router input-channel="csvTransformedChannel"
    ref="CommonMessageRouter" />

<bean id="CommonMessageRouter" class="com.ws.router.CommonMessageRouter" />

<!-- All CSV output from Endpoint's use this channel -->
<int:channel id="csvEnpointOutputChannel">
</int:channel>

<!-- Output Router based on responsecode from CSVResponse -->   
<int:recipient-list-router id="outPutRouter" input-channel="csvEnpointOutputChannel">
    <int:recipient channel="csvErrorChannel" selector-expression="payload.responseCode != 0"/>
    <int:recipient channel="csvOutputChannel" selector-expression="payload.responseCode == 0"/>
</int:recipient-list-router>

<!-- CSV Error Channel -->
<int:channel id="csvErrorChannel">
</int:channel>

<!-- CSV Output Channel -->
<int:channel id="csvOutputChannel">
</int:channel>


<!-- CSV Service Activators -->

<!-- Result Processing CSV Service Activator  -->

<int:service-activator input-channel="csvErrorChannel" output-channel="nullChannel">
        <bean class="com.ws.endpoint.csv.CSVErrorHandlerEndpoint"></bean>   
</int:service-activator>

<int:service-activator input-channel="csvOutputChannel" output-channel="nullChannel">
        <bean class="com.ws.endpoint.csv.CSVOutputHandlerEndpoint"></bean>  
</int:service-activator>


<!-- CSV Export Component Start-->

<!-- File/FTP Out Channel -->
<int-file:inbound-channel-adapter directory="${ftp.export.sync.folder}" channel="csvExportFileChannel" filename-pattern="*.csv" id="fileOutBond">
    <int:poller id="csvExportPoller" fixed-rate="${csv.poll.timeinterval}" default="false" error-channel="csvErrorChannel"/>    
</int-file:inbound-channel-adapter>

<int:channel id="csvExportFileChannel">
</int:channel>

<!-- Move the file to FTP Location and delte the source file located in local server -->
<int-ftp:outbound-channel-adapter session-factory="ftpClientFactoryOutBond" channel="csvExportFileChannel" 
                        remote-directory-expression="'/CSV/' + getPayload().getName().substring(21).substring(0,getPayload().getName().substring(21).indexOf('_'))"
                        auto-create-directory="true">
    <int-ftp:request-handler-advice-chain>
        <bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
            <property name="onSuccessExpression" value="payload.delete()" />
            <property name="successChannel" ref="nullChannel" />
        </bean>
    </int-ftp:request-handler-advice-chain>
</int-ftp:outbound-channel-adapter>

Heap Reference Tree

(1)org.springframework.integration.util.ErrorHandlingTaskExecutor@0x10a545c8 (16 bytes) 

    References to this object:
    (2)org.springframework.integration.util.ErrorHandlingTaskExecutor$1@0x4c05820 
    ... n number
    (keep increasing everytime polling)

    Now(2)
    org.springframework.integration.util.ErrorHandlingTaskExecutor$1@0x4c05820 

    has 

    task (L) : (3)org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller$1@0x4c05810 (12 bytes) 

    and  References to this object:
    java.util.concurrent.SynchronousQueue$TransferStack$SNode@0x4c05830 (28 bytes) :


    Now (3)org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller$1@0x4c05810 (12 bytes) 

    has Instance of 
    (4)org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller@0x10a3f690 (16 bytes) 

    which refers to n.no  of   org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller$1@0x4b4e718 (12 bytes) 

(keep increasing every time polls i.e every 3sec)

and (3)
    References to this object:
    org.springframework.integration.util.ErrorHandlingTaskExecutor$1@0x4c05820 (16 bytes) : field val$task
Annavi
  • 141
  • 1
  • 12

1 Answers1

0

You also have no consumer on csvFtpChannel so that queue will consume memory until something consumes from it.

You generally don't need to use a queue channel when you already have a task executor on the poller because it will cause an unnecessary additional thread handoff.

Also, if it wasn't a queue channel, you would have failed fast with Dispatcher has not consumers for csvFtpChannel.

EDIT

I don't know what you are using to examine the heap, but the ErrorHandlingTaskExecutor holds no references to its tasks.

In YourKit, I see a number of these objects but they are unreachable and will be removed during garbage collection.

If you still feel there's a problem, post the heap dump (e.g. in hprof format) to somewhere like pastebin.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Thanks Gary.Sorry i have attached the wrong configuration (i.e used Task Executor only for testing to see it helps).I have consumer for csvFtpChannel also am not using the taskexecutor.i have updated the correct one can please have look again.Also why the poller objects are filling the heap (AbstractPollingEndpoint$Poller) eveytime its polls.I am currently polling for every 3sec. – Annavi Jul 31 '15 at 13:46
  • Exactly what are you seeing on the heap, and where? When there's no task executor, the poller runs the `ErrorHandlingTaskExecutor$1` on the scheduler thread and it's not stored anywhere. – Gary Russell Jul 31 '15 at 15:23
  • Please answer my request: `Exactly what are you seeing on the heap, and where?`. i.e. what class/instance is holding a reference to the task objects. – Gary Russell Jul 31 '15 at 16:04
  • In heap am seeing ErrorHandlingTaskExecutor for each of my pollers expected. say my FTP poller polls every 3sec. everytime its polls its creating the ErrorHandlingTaskExecutor$1 (which has task AbstractPollingEndpoint$Poller$1) after some time my heap is flooded with ErrorHandlingTaskExecutor$1(which has task AbstractPollingEndpoint$Poller$1 ) and my FTP's ErrorHandlingTaskExecutor has reference to these objects so kind of my heap is getting full if i run my 4 channel adapers for every 3 sec as its creating new AbstractPollingEndpoint$Poller objects every time. is this expected behavior – Annavi Jul 31 '15 at 16:20
  • Also put the heap Reference Tree in the main Topic – Annavi Jul 31 '15 at 16:33
  • See my edit - you need to post a heap dump someplace if you disagree. – Gary Russell Jul 31 '15 at 18:30
  • Thanks Gary.I run and get one more heap dump and analyze further update if any issues on ErrorHandlingTaskExecutor . – Annavi Jul 31 '15 at 20:27
  • Any update on this issue? We are currently facing the same issue with a full heap of ErrorHandlingTaskExecutor$1 and AbstractPollingEndpoint$Poller$1 instances. – deradam Nov 10 '15 at 09:33
  • There __was__ no issue here. See my answer; the objects were gc'd. If you have a __new__ issue, ask a new question, showing your configuration and real __evidence__ that there's a problem. – Gary Russell Nov 10 '15 at 14:01