生成缩略图时出现pdf.js内存泄漏

时间:2015-05-13 17:00:36

标签: javascript node.js pdf pdf.js nw.js

我正在创建一个需要显示大量PDF的nw.js应用程序。首次启动应用程序时,最初会下载PDF。在初始化阶段,我还需要为列表中显示的每个PDF创建一个缩略图。

当我们有一些PDF时,缩略图生成本身似乎不是问题。它的工作原理是创建一个canvas元素,让PDF.js绘制第一页,然后将画布保存为PNG。

问题是PDF.js似乎无法在运行之间卸载PDF。加载20个1MB的PDF文件通常会导致使用大约500MB RAM的nw.js。现在我们将有100多个,甚至数千个PDF,所以我们需要弄清楚如何释放每个缩略图之间的RAM,因为大约80左右的PDF,nw.js已经使用2GB的RAM并冻结我的笔记本电脑,因为它内存耗尽。

我做了一个简单的测试,显示了这个问题:

var fs = require("fs");
var Q = require("q");
var glob = require("glob");

var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');

PDFJS.workerSrc = "pdf.worker.js";

function pdf(pdfFile) {
    return new Q.Promise(function (fulfill, reject) {
        PDFJS.getDocument(pdfFile).then(function (pdf) {

            pdf.getPage(1).then(function (page) {
                var viewport = page.getViewport(0.5);

                canvas.height = viewport.height;
                canvas.width = viewport.width;

                var renderContext = {
                    canvasContext: ctx,
                    viewport: viewport
                };

                page.render(renderContext).then(function () {
                    //set to draw behind current content
                    ctx.globalCompositeOperation = "destination-over";

                    //set background color
                    ctx.fillStyle = "#ffffff";

                    //draw background / rect on entire canvas
                    ctx.fillRect(0, 0, canvas.width, canvas.height);
                    var img = canvas.toDataURL("image/png");
                    img = img.replace(/^data:image\/png;base64,/, "");
                    fs.writeFile(pdfFile + ".png", img, 'base64', function (err) {
                        console.log("Done thumbnail for: " + pdfFile);
                        fulfill();
                    });
                });
            });
        });
    });
}

glob("pdf/*.pdf", function (err, files) {
    if (err) {
        console.log(err);
    } else {
        function generate(file) {
            console.log("Generating thumb for: " + file);
            pdf(file).then(function() {
                if(files.length > 0) next();
            });
        }
        function next() {
            var file = files.pop();
            generate(file);
        }

        next();
    }
});

我之前从未做过这样的事情。我试图为所有拇指重复使用相同的画布,但这似乎并没有改变一件事。

我曾尝试在开发人员工具中执行堆快照,以查看占用所有内存的内容,但猜猜是什么?它似乎在执行快照之前触发垃圾收集,因此在执行快照之前nw.js从500MB变为大约100MB。这让我相信对象实际上被标记为删除,但GC在计算机耗尽RAM之前从未有机会运行。加载20个文件,然后等待,但不会触发GC,也不会耗尽RAM。

我已经尝试检查PDF.js的API和文档,但在下载之前我找不到任何提及如何卸载PDF的内容。

关于我应该如何进行的任何想法?我的想法是调用一些外部工具或制作我将使用node-ffi调用的ac / c ++库,但是我必须使用PDF.js来显示以后的PDF状态而且我想我会再遇到同样的问题。

0 个答案:

没有答案