Skip to content

jszip runs out of memory when creating a zip file with 20,000 files #446

@dteviot

Description

@dteviot

Problem can be reproduced on Chrome, using the following files. Note, pkzip.js needs to be in same directory as this file.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Demonstrate jszip memory use</title>
    <base />
</head>
<body>
    <button id="prepZip">Prepare Zip</button>
    <button id="genZip">GenerateZip</button>
    <script src="jszip.js"></script>
<script>
"use strict";

class ZipTest {
    prepZip() {
        let content = "dummy";
        let zipOptions = { compression: "DEFLATE" };
        this.zipFile = new JSZip();
        for(let i = 0; i < 20000; ++i) {
            this.zipFile.file(`${i}.txt`, content, zipOptions);
        };
    }

    genZip() {
        return this.zipFile.generateAsync({ type: "blob" }).then(function (content) {;
            return Promise.resolve();
        })
    }

    init () {
        document.querySelector("#prepZip").onclick = this.prepZip.bind(this);
        document.querySelector("#genZip").onclick = this.genZip.bind(this);
    }
}

let test = new ZipTest();
test.init();
</script>
</body>
</html>

When above html file is first opened, memory shown in Task manager is 15 Megs.
After clicing PrepareZip, and forcing a Garbage collection, Memory is 32 Megs.
After clicking GenerateZip, memory climbs to more than 3 Gigs, then "Aw Snap" appears on Chrome.

The root cause seems to be generateWorker() in https://github.com/Stuk/jszip/blob/master/lib/generate/index.js
This creates a compression worker for each file to be compressed, before starting to compress any file.
Each worker contains 9 buffers that are 64 kbyte in length.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions