Uploaded image for project: 'OpenOLAT'
  1. OpenOLAT
  2. OO-4013

Thread loading QTI test on test completion ends up in infinite loop

    XMLWordPrintable

    Details

      Description

      We found a long running thread consuming 100% of one cpu core on our production system which seems to be caused by a corrupt HashMap data structure (maybe caused by a concurrent resize).

      The stack for the infinite looping thread is:

      "ForkJoinPool.commonPool-worker-25" #43138 daemon prio=5 os_prio=0 tid=0x00007f0e3487c000 nid=0x5171 runnable [0x00007f0d353f6000]
         java.lang.Thread.State: RUNNABLE
              at java.util.HashMap$TreeNode.balanceInsertion(HashMap.java:2234)
              at java.util.HashMap$TreeNode.treeify(HashMap.java:1943)
              at java.util.HashMap$TreeNode.split(HashMap.java:2175)
              at java.util.HashMap.resize(HashMap.java:714)
              at java.util.HashMap.putVal(HashMap.java:663)
              at java.util.HashMap.put(HashMap.java:612)
              at uk.ac.ed.ph.jqtiplus.resolution.CachedResourceProvider.getLookup(CachedResourceProvider.java:97)
              at uk.ac.ed.ph.jqtiplus.resolution.AssessmentObjectResolver.resolveAssessmentItem(AssessmentObjectResolver.java:82)
              at uk.ac.ed.ph.jqtiplus.resolution.AssessmentObjectResolver.lambda$initResolvedAssessmentTest$0(AssessmentObjectResolver.java:179)
              at uk.ac.ed.ph.jqtiplus.resolution.AssessmentObjectResolver$$Lambda$76/891886811.accept(Unknown Source)
              at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
              at java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1553)
              at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
              at java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291)
              at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
              at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
              at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
              at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
              at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
      

      Looking at the memory dump in the HashMap there seems to be a TreeNode referencing itself as the grandparent (found with MAT and the following query):

      SELECT * FROM java.util.HashMap$TreeNode WHERE parent != NULL and parent.parent.parent = parent
      

      Maybe in jqtiplus instead use a ConcurrentHashMap in the CachedResourceProvider?

        Attachments

          Activity

            People

            • Assignee:
              srosse Stéphane Rossé
              Reporter:
              d.haag Daniel Haag
              Tester:
              Mandy Menzel
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Time Tracking

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Remaining Estimate - 0 minutes
                0m
                Logged:
                Time Spent - 2 hours, 5 minutes
                2h 5m