Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-140853

Being close to the end island causes out of memory and file descriptor exhaustion

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved
    • Resolution: Fixed
    • Affects Version/s: Minecraft 18w48a, Minecraft 18w48b, Minecraft 18w49a
    • Fix Version/s: Minecraft 18w50a
    • Environment:
    • Confirmation Status:
      Confirmed

      Description

      Being in a certain distance to the end island causes a massive memory leak.
      Recreation can be seen in


      This happens since 18w44a.

      This first happened when Meri Diana and I tried to recreate MC-140808 and MC-137467.
      We were able to identify the render distance and the distance to 0,0 as important factors.

      Steps to reproduce

      1. Create new World (creative, cheats enabled)
      2. Set render distance to 8
      3. Go to the end /setblock ~ ~ ~ end_portal
      4. Fly to avoid falling into the void and teleport to /tp 140 70 0
      5. Press F3 and watch the memory usage grow to 100% in a couple of minutes

      Alternatively use the world download DragonEatsRam.zip with render distance 8.

      Issues

      Besides the massive memory leak, I also noticed random processes on my system shutting down.
      Further investigation showed that Minecraft spawned thousands of threads each keeping hundreds of file descriptors alive, completely exhausting the system resources.

      Meri Diana noticed that the snooper shows thousands of chunks being loaded in the overworld as well as the end, which may be related. since-18w43a.png
      In 1.13.2 the snooper shows only about a fifth to tenth of that in-1-13-2.png.
      However, interestingly this was already the case in 18w43a/b/c in which the memory leak doesn't happen.

      Cause

      The cause seems to be an armada of world generation threads spawned by the dragon fight manager.

      The fight manager makes sure a 17x17 area around 0,0 is loaded before it summons the dragon.
      Judging from the number of CompletableFuture instance created within a couple of seconds, it seems like it creates one for each chunk in each tick, but for some reason doesn't succeed loading them.
      Note: The dragon does not spawn, presumably because the area never gets loaded. Also see MC-137467.

      Stack trace of the main culprit.

      Stack trace:
      	java.util.concurrent.CompletableFuture.doThenCombine(CompletableFuture, BiFunction, Executor)
      	java.util.concurrent.CompletableFuture.thenCombine(CompletionStage, BiFunction)
      	m.b(CompletableFuture, CompletableFuture)
      	m$$Lambda$2093.153347328.apply(Object, Object)
      	java.util.stream.ReduceOps$1ReducingSink.accept(Object)
      	java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Consumer)
      	java.util.stream.AbstractPipeline.copyInto(Sink, Spliterator)
      	java.util.stream.AbstractPipeline.wrapAndCopyInto(Sink, Spliterator)
      	java.util.stream.ReduceOps$ReduceOp.evaluateSequential(PipelineHelper, Spliterator)
      	java.util.stream.AbstractPipeline.evaluate(TerminalOp)
      	java.util.stream.ReferencePipeline.reduce(Object, BiFunction, BinaryOperator)
      	m.b(List)
      	uj.a(bag, int, IntFunction)
      	uj.a(bag, int, bqe)
      	tz.a(bqe, uj)
      	tz.a(uj)
      	ue.a(uj, tz)
      	ue$$Lambda$2087.569814135.accept(Object)
      	java.lang.Iterable.forEach(Consumer)
      	ue.a(uj)
      	uj.l()				// WorldGenWorker.runTasks() ?
      	uj.b(int, int, bqe, boolean)	// WorldGenWorker.addTicket() <<< Probably a good point to start looking at
      	uj.a(int, int, bqe, boolean)	// WorldGenWorker.genChunk()
      	bas.a(int, int, bqe)		// createChunk()
      	bas.d(int, int)			// loadChunk()
      	brj.c(int, int, int, int)	// DragonFightManager.loadArena()
      	brj.a(int, int, int, int)
      	brj.a(brj, int, int, int, int)
      	brj$b.a()
      	brj$b.a(brj$b)
      	brj.b()				// DragonFightManager.tick() <<< Pretty sure the check could be better on top level too
      	brk.l()
      	uk.m_()
      	net.minecraft.server.MinecraftServer.b(BooleanSupplier)
      	net.minecraft.server.MinecraftServer.a(BooleanSupplier)
      	doq.a(BooleanSupplier)
      	net.minecraft.server.MinecraftServer.run()
      	java.lang.Thread.run()
      

      The underlying issue might relate to other currently reported world generation bugs and memory leaks, such as MC-138114 or MC-139930.
      However I wasn't able to find a post that matched the description closely enough to be sure.

        Attachments

        1. DragonEatsRam.zip
          2 kB
        2. in-1-13-2.png
          in-1-13-2.png
          31 kB
        3. JFR_AllocationByClass.png
          JFR_AllocationByClass.png
          138 kB
        4. JFR_AllocationByThread.png
          JFR_AllocationByThread.png
          77 kB
        5. JFR_HeapContent.png
          JFR_HeapContent.png
          70 kB
        6. JFR_HeapGrow.png
          JFR_HeapGrow.png
          57 kB
        7. JFR_HeapUsage.png
          JFR_HeapUsage.png
          35 kB
        8. MC140853.mp4
          7.98 MB
        9. oom.png
          oom.png
          158 kB
        10. since-18w43a.png
          since-18w43a.png
          32 kB

          Issue Links

            Activity

              People

              • Assignee:
                fry [Mojang] Georgii Gavrichev
                Reporter:
                panda4994 Panda
              • Votes:
                8 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  CHK: