-
Notifications
You must be signed in to change notification settings - Fork 506
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
how to reduce memory usage with streams? is chunkSize being ignored? #413
Comments
I used this test to answer your questions. It generates 4GB of data to compress on the fly and does not store the compressed data. On paper, this test should not leak memory because no data is stored. https://plnkr.co/edit/tUWLHBVp3xHyxSqh import * as zip from "https://unpkg.com/@zip.js/zip.js/index.js";
let total = 0;
class LogWriter extends zip.Writer {
writeUint8Array(array) {
out.innerHTML = "write " + array.length + " bytes <br>" + out.innerHTML;
}
}
class LogReader extends zip.Reader {
init() {
this.size = 4 * 1024 * 1024 * 1024;
}
readUint8Array(offset, length) {
const ONE_KB_DATA = Array.from(
crypto.getRandomValues(new Uint8Array(1024))
);
const size = Math.ceil(length / 1024);
const data = new Uint8Array(Array(size).fill(ONE_KB_DATA).flat());
total += data.length;
out.innerHTML =
"read " +
data.length +
" bytes (" +
Math.floor(total / (1024 * 1024)) +
"/" +
this.size / (1024 * 1024) +
")<br>" +
out.innerHTML;
return data;
}
}
async function test() {
zip.configure({ chunkSize: 16 * 1024 * 1024 });
out.innerHTML += "START<br>";
const zipWriter = new zip.ZipWriter(new LogWriter());
zipWriter.add("test", new LogReader(), {});
zipWriter.close();
}
test(); It shows that |
Here's what my setup looks like (minus a bunch of console.logs and error handling):
Here, I understand that some of these chunks are for zip metadata but the largest chunk coming through is 2mb. As for the memory leak, I have not gotten very far debugging it. I suspected web workers at first but the same thing happens with |
On second though, I think the https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamDefaultReader
This seems like a possible explanation for the memory issue. I'll play with https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamBYOBReader
|
For the record, |
I've found the cause of the issue, it was related to the usage of |
Amazing! I'll give it a try and let you know if it works on my end. |
I tested Quick question ... with compression set to 0 via Thanks for the super quick fix! I really appreciate your effort to get this resolved! |
I'm glad to hear you confirm it's fixed on your end as well. Even with level set to 0, zip.js will need to compute the CRC32 signature used to verify the integrity of the data. The compression logic is entirely bypassed though. |
Hello! Thank you for this library!
I'm experimenting with
zip.js
to determine whether or not I can use it for a production service I maintain involving unlimited file transfers. The idea is to zip files client side and stream the zip from sender to receiver. The other piece of the experiment is to use Cloudflare Workers as the proxy to route the bytes from sender to receiver.Good news, I have it working! However, I'm running into 2 issues that I hope to get help with.
The first issue I'm seeing is that memory usage grows to be as large as the files being transferred. For example, sending gigabytes leads to gigabytes of memory usage.
The screenshot shows
zip.js
using 4.8gb of memory for a transfer of 4 files, each being a little over 1gb. The reason for streaming is to allow for unlimited transfers; no limit on how many files can be transfered or how large each file can be.I have not yet figured out why this is happening but I suspect it has something to do with the final zip file. According to the docs, calling
zip.close()
returns a promise of the contents of the zip. For my use case, the sender does not need the final zip and sozip.close()
doesn't need to return anything.How can I avoid this?
The second issue is with configuring
chunkSize
. I have not been able to get it to take effect. As far as I can tell, I just need to callconfigure()
once globally, which I've done:In this example, I'm setting
chunkSize
to 10mb but none of the requests have theContent-Length
header equal to the chunk size I've configured. In all these transfer requests,Content-Length
varies but 2mb is the largest as far as I can tell.What am I doing wrong with
chunkSize
?The text was updated successfully, but these errors were encountered: