3 Replies Latest reply on Jan 24, 2007 7:36 AM by johan.parent

    Is this a mem. leak

    johan.parent

      Hi all,

      As a test I have wrapped up the Websale demo code in a loop. In the loop a process is instantiated (one at a time) and the different tasks are handled (See fullCycle() in code below).

      Initially one iteration takes 0.2 secs (not too fast...) but performance drops after a while.

      After some 4000 iterations the process consumes 256+Mb of mem (and with my jvm settings) slows down to a crawl. As far as I can see the jvm spends most of its time doing "stop the world" gc's.

      I put the code below. Can anyone take the code and try to reproduce the drop in performance and/or increasing mem. consumption?

      Note you'll need a few more files which come with the starters kit.

      Regards,

      Johan


      package JBpmTest;
      
      /**
       * Created by IntelliJ IDEA.
       * User: jparent
       * Date: 15-jan-2007
       * Time: 13:26:08
       * To change this template use File | Settings | File Templates.
       */
      public class MainWebsaleTest {
       static public void main(String[] args) {
       WebsaleTest sale = new WebsaleTest();
       int loops[] = { 5000 };
       JBpmTiming timer = new JBpmTiming("global");
       JBpmTiming one = new JBpmTiming("single");
      
       try {
       sale.setUp();
      
       for (int count = 0; count<loops.length; count++) {
       System.out.println("Number of loops " + loops[count]);
      
       timer.reset();
       timer.start();
       for (int i = 0; i<loops[count]; i++) {
       one.reset();
       one.start();
       sale.fullCycle();
       System.out.println(i + " " + one.stop());
       }
      
       timer.stop();
       System.out.println("Number of loops " + loops[count]);
       timer.print();
       }
      
       sale.tearDown();
       }
       catch(Exception e) {
       e.printStackTrace();
       }
       }
      }
      



      The slightly MODIFIED Websale

      package JBpmTest;
      
      /**
       * Created by IntelliJ IDEA.
       * User: jparent
       * Date: 15-jan-2007
       * Time: 13:00:29
       * To change this template use File | Settings | File Templates.
       */
      /*
      public class WebsaleTest {
      }
      */
      
      
      import java.util.HashMap;
      import java.util.List;
      import java.util.Map;
      
      import org.jbpm.JbpmConfiguration;
      import org.jbpm.context.exe.ContextInstance;
      import org.jbpm.db.AbstractDbTestCase;
      import org.jbpm.graph.def.ProcessDefinition;
      import org.jbpm.graph.exe.ProcessInstance;
      import org.jbpm.identity.Entity;
      import org.jbpm.identity.hibernate.IdentitySession;
      import org.jbpm.identity.xml.IdentityXmlParser;
      import org.jbpm.taskmgmt.exe.TaskInstance;
      import org.jbpm.taskmgmt.exe.TaskMgmtInstance;
      
      public class WebsaleTest extends AbstractDbTestCase {
      
       JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();
      
       ProcessDefinition processDefinition = null;
       ProcessInstance processInstance = null;
       ContextInstance contextInstance = null;
       TaskMgmtInstance taskMgmtInstance = null;
       long processInstanceId = -1;
      
       boolean doUnitTest = false;
      
       public void setUp() throws Exception {
       super.setUp();
       deployProcess();
       loadIdentities();
       newTransaction();
       }
      
       private void deployProcess() {
       ProcessDefinition processDefinition =
       ProcessDefinition.parseXmlResource("websale.par/processdefinition.xml");
       jbpmContext.deployProcessDefinition(processDefinition);
       }
      
       private void loadIdentities() {
       // load the identities
       Entity[] entities = IdentityXmlParser.parseEntitiesResource("hsqldb/identity.db.xml");
       IdentitySession identitySession = new IdentitySession(session);
       for (int i=0; i<entities.length; i++) {
       identitySession.saveEntity(entities);
       }
       newTransaction();
       }
      
       private void createNewProcessInstance() {
       processDefinition = graphSession.findLatestProcessDefinition("websale");
       processInstance = new ProcessInstance(processDefinition);
       contextInstance = processInstance.getContextInstance();
       taskMgmtInstance = processInstance.getTaskMgmtInstance();
       }
      
      
       public void testWebSaleOrderTaskParameters() {
       TaskInstance taskInstance = processInstance.getTaskMgmtInstance().createStartTaskInstance();
       assertEquals("create new web sale order", taskInstance.getName());
       assertEquals(0, taskInstance.getVariables().size());
       }
      
       public void testPerformWebSaleOrderTask() {
       TaskInstance taskInstance = null;
      
       jbpmContext.setActorId("cookie monster");
       // create a task to start the websale process
       taskInstance = processInstance.getTaskMgmtInstance().createStartTaskInstance();
      
       Map taskVariables = new HashMap();
       taskVariables.put("item", "cookies");
       taskVariables.put("quantity", "lots of them");
       taskVariables.put("address", "sesamestreet 46");
      
       taskInstance.addVariables(taskVariables);
       taskInstance.end();
      
       assertEquals("cookies", contextInstance.getVariable("item"));
       assertEquals("lots of them", contextInstance.getVariable("quantity"));
       assertEquals("sesamestreet 46", contextInstance.getVariable("address"));
       assertEquals("cookie monster", taskMgmtInstance.getSwimlaneInstance("buyer").getActorId());
       }
      
       public void testEvaluateAssignment() {
       TaskInstance taskInstance = null;
      
       jbpmContext.setActorId("cookie monster");
       // create a task to start the websale process
       taskInstance = processInstance.getTaskMgmtInstance().createStartTaskInstance();
       taskInstance.setVariable("item", "cookies");
       taskInstance.end();
       jbpmContext.save(processInstance);
       processInstanceId = processInstance.getId();
      
       newTransaction();
      
       List erniesTasks = taskMgmtSession.findTaskInstances("ernie");
       assertEquals(1, erniesTasks.size());
      
       TaskInstance evaluateTaskInstance = (TaskInstance) erniesTasks.get(0);
       assertEquals("ernie", evaluateTaskInstance.getActorId());
       assertEquals("evaluate web order", evaluateTaskInstance.getName());
       assertNotNull(evaluateTaskInstance.getToken());
       assertNotNull(evaluateTaskInstance.getCreate());
       assertNull(evaluateTaskInstance.getStart());
       assertNull(evaluateTaskInstance.getEnd());
       }
      
       public void testEvaluateOk() {
       TaskInstance taskInstance = processInstance.getTaskMgmtInstance().createStartTaskInstance();
       taskInstance.end();
       jbpmContext.save(processInstance);
      
       newTransaction();
      
       TaskInstance evaluateTaskInstance = (TaskInstance) taskMgmtSession.findTaskInstances("ernie").get(0);
       evaluateTaskInstance.end("ok");
       jbpmContext.save(evaluateTaskInstance);
      
       newTransaction();
      
       List erniesTasks = taskMgmtSession.findTaskInstances("bert");
       assertEquals(1, erniesTasks.size());
      
       TaskInstance waitForMoneyTaskInstance = (TaskInstance) erniesTasks.get(0);
       assertEquals("bert", waitForMoneyTaskInstance.getActorId());
       assertEquals("wait for money", waitForMoneyTaskInstance.getName());
       assertNotNull(waitForMoneyTaskInstance.getToken());
       assertNotNull(waitForMoneyTaskInstance.getCreate());
       assertNull(waitForMoneyTaskInstance.getStart());
       assertNull(waitForMoneyTaskInstance.getEnd());
       }
      
       public void testUnwritableVariableException() {
       testEvaluateAssignment();
       newTransaction();
       List erniesTasks = taskMgmtSession.findTaskInstances("ernie");
       TaskInstance evaluateTaskInstance = (TaskInstance) erniesTasks.get(0);
       // this variable is set in the task instance variables, but
       // should not be submitted to the process context variables.
       evaluateTaskInstance.setVariable("item", "this is not allowed");
       evaluateTaskInstance.end();
      
       newTransaction();
      
       processInstance = graphSession.loadProcessInstance(processInstanceId);
       contextInstance = processInstance.getContextInstance();
       // so the cookies should still be in the item process variable.
       assertEquals("cookies", contextInstance.getVariable("item"));
       }
      
       public void testEvaluateNok() {
       testEvaluateAssignment();
       newTransaction();
      
       List erniesTasks = taskMgmtSession.findTaskInstances("ernie");
       TaskInstance evaluateTaskInstance = (TaskInstance) erniesTasks.get(0);
       evaluateTaskInstance.setVariable("comment", "wtf");
       evaluateTaskInstance.end("more info needed");
       jbpmContext.save(evaluateTaskInstance);
      
       newTransaction();
      
       List cookieMonsterTasks = taskMgmtSession.findTaskInstances("cookie monster");
       assertEquals(1, cookieMonsterTasks.size());
       TaskInstance fixWebOrderDataTaskInstance = (TaskInstance) cookieMonsterTasks.get(0);
       assertEquals("cookie monster", fixWebOrderDataTaskInstance.getActorId());
       assertEquals("wtf", fixWebOrderDataTaskInstance.getVariable("comment"));
       }
      
       public void testMoreInfoNeeded() {
       TaskInstance taskInstance = null;
      
       jbpmContext.setActorId("cookie monster");
      
       // create a task to start the websale process
       taskInstance = processInstance.getTaskMgmtInstance().createStartTaskInstance();
       taskInstance.end();
       jbpmContext.save(processInstance);
      
       newTransaction();
      
       TaskInstance evaluateTaskInstance = (TaskInstance) taskMgmtSession.findTaskInstances("ernie").get(0);
       evaluateTaskInstance.end("more info needed");
       jbpmContext.save(evaluateTaskInstance);
      
       newTransaction();
      
       List cookieMonsterTasks = taskMgmtSession.findTaskInstances("cookie monster");
       assertEquals(1, cookieMonsterTasks.size());
      
       TaskInstance fixWebOrderDataTaskInstance = (TaskInstance) cookieMonsterTasks.get(0);
       assertEquals("cookie monster", fixWebOrderDataTaskInstance.getActorId());
       assertEquals("fix web order data", fixWebOrderDataTaskInstance.getName());
       assertNotNull(fixWebOrderDataTaskInstance.getToken());
       assertNotNull(fixWebOrderDataTaskInstance.getCreate());
       assertNull(fixWebOrderDataTaskInstance.getStart());
       assertNull(fixWebOrderDataTaskInstance.getEnd());
       }
      
       public void fullCycle() {
       createNewProcessInstance();
      
       TaskInstance taskInstance = null;
      
       jbpmContext.setActorId("cookie monster");
       // create a task to start the websale process
       taskInstance = processInstance.getTaskMgmtInstance().createStartTaskInstance();
       taskInstance.setVariable("item", "cookies");
       taskInstance.end();
       jbpmContext.save(processInstance);
       processInstanceId = processInstance.getId();
      
       newTransaction();
      
       List erniesTasks = taskMgmtSession.findTaskInstances("ernie");
      
       if (doUnitTest)
       assertEquals(1, erniesTasks.size());
      
       if (erniesTasks.size() > 0) {
       TaskInstance evaluateTaskInstance = (TaskInstance) erniesTasks.get(0);
      
       if (doUnitTest) {
       assertEquals("ernie", evaluateTaskInstance.getActorId());
       assertEquals("evaluate web order", evaluateTaskInstance.getName());
       assertNotNull(evaluateTaskInstance.getToken());
       assertNotNull(evaluateTaskInstance.getCreate());
       assertNull(evaluateTaskInstance.getStart());
       assertNull(evaluateTaskInstance.getEnd());
       }
       }
       newTransaction();
      
       erniesTasks = taskMgmtSession.findTaskInstances("ernie");
       if (erniesTasks.size() > 0) {
       TaskInstance evaluateTaskInstance = (TaskInstance) erniesTasks.get(0);
       evaluateTaskInstance.setVariable("comment", "wtf");
       evaluateTaskInstance.end("more info needed");
       jbpmContext.save(evaluateTaskInstance);
       }
      
       newTransaction();
      
       List cookieMonsterTasks = taskMgmtSession.findTaskInstances("cookie monster");
       if (doUnitTest)
       assertEquals(1, cookieMonsterTasks.size());
      
       if (cookieMonsterTasks.size() > 0) {
       TaskInstance fixWebOrderDataTaskInstance = (TaskInstance) cookieMonsterTasks.get(0);
       if (doUnitTest) {
       assertEquals("cookie monster", fixWebOrderDataTaskInstance.getActorId());
       assertEquals("wtf", fixWebOrderDataTaskInstance.getVariable("comment"));
       }
      
       fixWebOrderDataTaskInstance.end();
       }
      
       newTransaction();
      
       erniesTasks = taskMgmtSession.findTaskInstances("ernie");
      
       if (erniesTasks.size() > 0) {
       TaskInstance evaluateTaskInstance = (TaskInstance) erniesTasks.get(0);
       evaluateTaskInstance.setVariable("comment", "IS OK NOW");
       evaluateTaskInstance.end("ok");
       jbpmContext.save(evaluateTaskInstance);
       }
      
       newTransaction();
      
       List bertTasks = taskMgmtSession.findTaskInstances("bert");
       if (doUnitTest)
       assertEquals(1, bertTasks.size());
      
       if (bertTasks.size() > 0) {
       TaskInstance waitForMoneyTaskInstance = (TaskInstance) bertTasks.get(0);
       if (doUnitTest) {
       assertEquals("bert", waitForMoneyTaskInstance.getActorId());
       assertEquals("wait for money", waitForMoneyTaskInstance.getName());
       assertNotNull(waitForMoneyTaskInstance.getToken());
       assertNotNull(waitForMoneyTaskInstance.getCreate());
       assertNull(waitForMoneyTaskInstance.getStart());
       assertNull(waitForMoneyTaskInstance.getEnd());
       }
      
       waitForMoneyTaskInstance.end();
       }
      
       List groverTasks = taskMgmtSession.findTaskInstances("grover");
       if (doUnitTest)
       assertEquals(1, groverTasks.size());
      
       if (groverTasks.size() > 0) {
       TaskInstance shippingTask = (TaskInstance) groverTasks.get(0);
       shippingTask.end();
       }
      
       // Setup new session & co for next loop (not inside this method)
       newTransaction();
       }
       }
      


      And the timing utility

      package JBpmTest;
      
      /**
       * Created by IntelliJ IDEA.
       * User: jparent
       * Date: 19-dec-2006
       * Time: 10:50:59
       * To change this template use File | Settings | File Templates.
       */
      public class JBpmTiming {
       private long total;
       private long min, max;
       private long count;
       private long start_time;
       String label;
      
       public JBpmTiming(String l) {
       reset();
       count = 0;
       min = 100000L;
       max = -1000000L;
       label = l;
       }
      
       public JBpmTiming() {
       this("Unknown");
       }
      
       public void start() {
       count++;
       start_time = System.currentTimeMillis ();
       }
      
       public long stop() {
       long ret = System.currentTimeMillis () - start_time ;
       total += ret;
      
       if (ret > max)
       max = ret;
      
       if (ret < min)
       min = ret;
      
       return ret;
       }
      
       public void accumulate(JBpmTiming in) {
       total += in.total;
       count += in.count;
      
       if (in.max > max)
       max = in.max;
      
       if (in.min < min)
       min = in.min;
       }
      
       void reset() {
       total = 0;
       count = 0;
       }
      
       public void print() {
       System.out.println("Name: " + label + " " + total+ "/" + min + "/" + max + "[" + total / (double)count + "|" + count + "] (tot/min/max[avg|nbr])");
       }
      }