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

    • Icon: Bug Bug
    • Resolution: Fixed
    • Minecraft 18w50a
    • Minecraft 18w48a, Minecraft 18w48b, Minecraft 18w49a
    • Confirmed

      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 LapisDemon 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.

      LapisDemon 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.

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

            fry [Mojang] Georgii Gavrichev
            panda4994 [Mojang] Panda
            Votes:
            8 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved:
              CHK: