Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Heap overflow when splitting large files #961

Open
ByThePowerOfScience opened this issue May 11, 2024 · 0 comments
Open

Heap overflow when splitting large files #961

ByThePowerOfScience opened this issue May 11, 2024 · 0 comments

Comments

@ByThePowerOfScience
Copy link

ByThePowerOfScience commented May 11, 2024

Context:

I have a replay that is eight hours long. I tried to fast forward halfway, and my client ran out of the 8GB of heap memory I have allocated. I'll be analyzing the heap dump and making another issue once I identify the problem with that.

Anyway, I relaunched Minecraft and tried splitting the replay into sections. Soon after, it ran out of heap memory again.

Problem:

// Don't be sad, have a hug! <3

Time: 2024-05-11 00:09:15
Description: Running marker processor

java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Arrays.java:3481) ~[?:?] {re:mixin}
	at java.util.ArrayList.grow(ArrayList.java:237) ~[?:?] {re:mixin}
	at java.util.ArrayList.grow(ArrayList.java:244) ~[?:?] {re:mixin}
	at java.util.ArrayList.add(ArrayList.java:486) ~[?:?] {re:mixin}
	at java.util.ArrayList$ListItr.add(ArrayList.java:1068) ~[?:?] {}
	at com.replaymod.replaystudio.stream.IteratorStream.insert(IteratorStream.java:54) ~[replaymod-1.20.1-2.6.15_mapped_srg_1.20.1.jar%231153!/:?] {re:classloading}
	at com.replaymod.replaystudio.filter.SquashFilter.add(SquashFilter.java:819) ~[replaymod-1.20.1-2.6.15_mapped_srg_1.20.1.jar%231153!/:?] {re:classloading}
	at com.replaymod.replaystudio.filter.SquashFilter.onEnd(SquashFilter.java:773) ~[replaymod-1.20.1-2.6.15_mapped_srg_1.20.1.jar%231153!/:?] {re:classloading}
	at com.replaymod.editor.gui.MarkerProcessor.apply(MarkerProcessor.java:168) ~[replaymod-1.20.1-2.6.15_mapped_srg_1.20.1.jar%231153!/:?] {re:classloading}
	at com.replaymod.editor.gui.GuiEditReplay.lambda$apply$12(GuiEditReplay.java:164) ~[replaymod-1.20.1-2.6.15_mapped_srg_1.20.1.jar%231153!/:?] {re:classloading}
	at com.replaymod.editor.gui.GuiEditReplay$$Lambda$52301/0x00000008063c9278.run(Unknown Source) ~[?:?] {}
	at java.lang.Thread.run(Thread.java:833) ~[?:?] {re:mixin}

try (ReplayOutputStream replayOutputStream = outputReplayFile.writePacketData()) {
if (cutFilter != null) {
cutFilter.release();
cutFilter = squashFilter.copy();
} else if (splitCounter > 0) {
List<PacketData> packets = new ArrayList<>();
squashFilter.copy().onEnd(
new IteratorStream(packets.listIterator(), (StreamFilter) null),
timeOffset
);
for (PacketData packet : packets) {
replayOutputStream.write(0, packet.getPacket());
}
}

Essentially, it seems that the entire replay gets buffered into a list before being committed to the file. This is fine for smaller replays, but for larger ones it ends up overflowing the allocated heap memory.

Solution:

Directly append each packet onto the file without buffering them first.

I can make the PR for this, but could you please help me understand what this section of code is doing so I don't break anything when fixing it?

@ByThePowerOfScience ByThePowerOfScience changed the title Heap overflow when working with large files Heap overflow when splitting large files May 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant