Announcement Announcement Module
Collapse
No announcement yet.
Memory leak ? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Memory leak ?

    Hi all,

    I seem to have a memory leak in the application I just developed, which seems to be related to the model mapper of webflow.

    I have a simple page containing a list of radio buttons.
    On selection, a request is made to the server which allows me to keep in my flow bean the ID selected of an element from this list driven by the radio buttons.

    As far as I saw, on each request webflow :
    1. Create a NEW instance my model
    2. Populate this instance with the data coming from the view
    3. Store this instance in the flowscope replacing the previous instance present there.

    I've monitored my webapp memory via Probe: http://code.google.com/p/psi-probe/ and saw that at the end of each cycle defined above, my session memory footprint kept increasing constantly as I was repeating the cycle.

    Thus my suspicion of a leak somewhere.

    Are the previous instance of the model kept somewhere ? calling a GC doesn't seems to release any memory.

    Thanks in advance,
    Best Regards.
    Farid

  • #2
    Hello Farid

    I have a simple page containing a list of radio buttons.
    On selection, a request is made to the server
    which allows me to keep in my flow bean the ID selected of an element from this list driven by the radio buttons.
    About the bold part, is based with AJAX?

    As far as I saw, on each request webflow :
    1. Create a NEW instance my model
    2. Populate this instance with the data coming from the view
    3. Store this instance in the flowscope replacing the previous instance present there.
    post some code, to have a better idea what are you doing, with only words we can't do a deeper diagnostic, maybe you are missing some detail or maybe you are something wrong

    Comment


    • #3
      Hiya,
      tks for the reply.

      I do not use ajax, my fields are defined within a form which is submitted on a selection, and the whole page is refreshed.

      here is an extract of my flow:

      Code:
      <!-- Step 1: Flow object declaration and creation -->
      <var name="managerData" class="com.x.x.tunnelvente.flows.ManagerData" />
      <var name="reservationData" class="com.x.x.tunnelvente.modeles.ReservationData" />
      
      <!-- Some init data and action states -->
      <!-- ... -->
      
      <!-- Main view -->
      <view-state id="etape1Vue" view="layouts/layout1" model="reservationData">
      	<on-render>
      		<set name="requestScope.contentView" value="'etape1'" />
      	</on-render>
      	<transition on="refreshRepartition" to="refreshRepartition" />
      	<transition on="refreshFormule" to="refreshFormule" />
      	<transition on="refreshAddon" to="refreshAddon" />
      	<transition on="refreshAssurance" to="refreshAssurance" />
      	<transition on="submit" to="submitEtape1" />
      </view-state>
      
      <!-- States called when an element has been selected in the form -->
      <action-state id="refreshRepartition">
      	<evaluate expression="managerData.refreshRepartition(reservationData)" />
      	<transition to="etape1Vue" />
      </action-state>
      
      <!-- ... -->
      The page is rendered by the state etape1Vue, and present a list of radio buttons for different lists.
      When a user click on a radio button, a hidden field in my form is updated and the form is submitted:
      Code:
      <input type="hidden" id="flowEventID" name="_eventId" value="nextState"/>
      For exemple, if the user click on one of the radio buttons related to the "Repartition List", the field named "_eventId" would be updated with the value "refreshRepartition" and the form submitted.

      The flow would then execute the action state "refreshRepartition" for some business process, and then redirected to the previous view state in order to display the updated page to the user.

      From what i have been able to see, every time a radio button is selected, WebFlow :
      1. Creates a new instance of my model "reservationData".
      2. Fills it with the data coming from the view.
      3. Validate this new instance of the model.
      4. and overwrite the previous instance of the model in the flowscope declared via <var name="managerData" class="com.x.x.tunnelvente.flows.ManagerData" /> with the newly instance created.

      While selecting continuously different radio button to execute the cycle a few times and with the help of the previously named monitoring tool, i could see that my session memory kept growing after each cycle.
      Forcing a GC didn't reduce it, meaning that either some hard reference are being kept (I assume on the previous instance of the model ?), or something else.

      I hope this helps clarify the issue i am facing.

      EDIT: I am using Spring 3.0.5 and webflow 2.2.0
      Best regards,
      Farid
      Last edited by fbengrid; Nov 29th, 2010, 05:29 AM.

      Comment


      • #4
        Spring webflow takes snapshots of the state (the previous state) those are stored in the repository which is tied to the session (you can configure/program it otherwise). So yes your state is stored, how much depends on your configuration.

        All that is explained in the reference guide (flow execution repository).

        Comment


        • #5
          Thanks marten, that was indeed the source of the problem.
          Adding
          Code:
          <flow:flow-execution-repository max-executions="5" max-execution-snapshots="3" />
          to keep only 3 previous states in memory solved its continuous growth i was experiencing.
          Thanks a lot.

          Best regards.
          Farid

          Comment


          • #6
            thanks for sharing this Farid. Any reason why you chose max-execution-snapshots as 3, whynot just 1 or 2? If it is 1, your memory could perform even better,right.
            thx.

            Comment


            • #7
              I imagine he wanted the user to be able to use the back button up to 2 times. When setting up your max executions and max execution snapshots, it's always a design decision between memory concerns and user convenience. One of SWF's features is very robust back-button support. Seems a shame to toss out the feature completely.

              Comment


              • #8
                hi all,
                Indeed it's in order to be able to press the back button at least 2 times.

                This will mean that the memory used by the application will be slightly higher (about 2.5 times from my mesurement) per user session, but it's a small price to pay in regard to the exception i would get if i had set it to 1. At least now my memory doesn't grow continously.

                A bit of a pain this exception to tell the truth, but well..

                Farid.

                Comment


                • #9
                  Originally posted by fbengrid View Post
                  hi all,
                  Indeed it's in order to be able to press the back button at least 2 times.

                  This will mean that the memory used by the application will be slightly higher (about 2.5 times from my mesurement) per user session, but it's a small price to pay in regard to the exception i would get if i had set it to 1. At least now my memory doesn't grow continously.

                  A bit of a pain this exception to tell the truth, but well..

                  Farid.
                  You can catch it and handle it, you know, either through a filter or some other means.

                  In my app, I redirect to an error page telling them they can't use the back button or history past that point, and giving them a link which simply does a history.forward().

                  A bit cleaner than just a stack trace.

                  Comment


                  • #10
                    yes, i do that already for the exceptions my process throws:
                    Code:
                    	<global-transitions>
                    		<transition
                    			on-exception="com.x.modules.DisponibiliteProduitException"
                    			to="DisponibiliteProduitErreurVue" />
                    		<transition
                    			on-exception="com.x.modules.DisponibiliteDateException"
                    			to="DisponibiliteDateErreurVue" />
                    		<transition
                    			on-exception="com.x.modules.SystemeException"
                    			to="ErreurSystemeVue" />
                    	</global-transitions>
                    but I need to check out how to isolate a "back" related exception from any other types of exception that WebFlow would throw.

                    Do you know how to isolate it ?

                    Farid

                    Comment


                    • #11
                      Originally posted by fbengrid View Post
                      yes, i do that already for the exceptions my process throws:
                      Code:
                      	<global-transitions>
                      		<transition
                      			on-exception="com.x.modules.DisponibiliteProduitException"
                      			to="DisponibiliteProduitErreurVue" />
                      		<transition
                      			on-exception="com.x.modules.DisponibiliteDateException"
                      			to="DisponibiliteDateErreurVue" />
                      		<transition
                      			on-exception="com.x.modules.SystemeException"
                      			to="ErreurSystemeVue" />
                      	</global-transitions>
                      but I need to check out how to isolate a "back" related exception from any other types of exception that WebFlow would throw.

                      Do you know how to isolate it ?

                      Farid
                      I don't believe you can handle it from within a flow definition at all, since the exception occurs because no flow could be restored. You'll need an alternate means.

                      Comment

                      Working...
                      X