viewer.js / pdf.js:每次呈现PDF时内存使用量都会增加

5
我的问题是,当我使用viewer.js渲染pdf文件时,应用程序的内存使用量会随着每次渲染而增加。
我通过以下方式渲染我的PDF文档:
container = document.getElementById('viewerContainer');
viewer = document.getElementById('viewer');

pdfViewer = new PDFViewer({
    container: container,
    viewer: viewer
});

$scope.pdfFindController = new PDFFindController({
      pdfViewer: pdfViewer
});

pdfViewer.setFindController($scope.pdfFindController);

container.addEventListener('pagesinit', function () {
    pdfViewer.currentScaleValue = 'page-width';                            
});

PDFJS.getDocument($scope.getPageLink(pdf)).then(function (pdfDocument) {
    documentPdf = pdfDocument;
    pdfViewer.setDocument(pdfDocument);                       
});

我在一个单独的视图中呈现文件。当我回到之前的视图并打开另一个文件时,内存使用量会增加约20MB。

我尝试了以下方法:

documentPdf.destroy();

现在,内存使用量减少了一点,但并没有像之前分配的那么多。

有没有解决方法?

更新:

Pdf.js版本:1.6.210

pdf.js工作线程版本:1.6.210


确保在运行垃圾回收后测量内存(一些浏览器可以通过它们的工具强制进行GC以完成此操作)。如果您要在同一页上使用多个文档,则建议使用相同的PDFWorker。documentPdf.destroy();是正确的步骤。如果您不重新使用相同的pdfViewer来设置文档,请确保清理所有对旧文档的引用,包括pdfFindController。 - async5
pdfjs项目中没有可用的angularjs包。如果没有提供完整的示例或未提及使用的包(供应商),则很难确定或重现。 - async5
我使用Xcode来查看内存使用情况,因为我是为iOS构建的。PDFWorker应该是一样的。我每次只需设置引用 PDFJS.workerSrc = 'lib/pdfviewer/pdf.worker.js';。我按照Giovazz89的建议删除并设置了变量。可能是viewer.js /pdf.js仍然有一些引用吗?实际上,它们应该被覆盖,并且我也在那个文件中销毁了文档。是否可能在一个文件中清除所有变量? - chocolate cake
看起来是iOS的问题。你在普通浏览器上是否也遇到了同样的问题?你没有发布最小化、完整和可验证的示例——这可能有助于解决你的问题。 - async5
有点复杂。我无法在浏览器中启动它,因为我的应用程序需要另一个应用程序才能工作。不幸的是,我没有时间构建一个示例。我会尝试,但不能保证。 - chocolate cake
2个回答

13

你需要在DocumentPageProxy的Promise上调用destroy方法。

文档描述如下:

销毁当前文档实例并终止工作线程。

来源:https://github.com/mozilla/pdf.js/blob/master/src/display/api.js(第621行)

当前的 pdf.js 库中有一些测试,测试了destroy方法的行为。 (https://github.com/mozilla/pdf.js/blob/master/test/unit/api_spec.js (第86行)

在你的情况下,可以这样做:

 // a variable to store the callback function
 var loadingTask = PDFJS.getDocument(basicApiUrl);
 
...

 // when the document should get destroyed call
 loadingTask.destroy();
 

谢谢你的回答。对我来说,这个问题已经过时了,因为我将使用cordova pdf viewer插件,它比pdf.js效果要好得多:https://github.com/sitewaerts/cordova-plugin-document-viewer - chocolate cake
3
我曾经遇到过同样的问题,然后在pdf.js中进行了分析 - 然后我发现了你的帖子,至少我回答了它。有时候我会回答其他帖子以供个人记录;) - duffy356

1
我认为通过调用documentPdf.destroy();并不能释放pdfViewer占用的内存: 我没有找到任何销毁pdfViewer的方法,但你可以尝试调用。
delete pdfViewer;
delete documentPdf;

如果你不确定删除属性是否足够,你可以将两者都设置为null

如果仍然出现内存泄漏,可能是历史缓存中存储的HTML占用了您的内存,因此请尝试使用空元素(或完全删除它)替换查看器或容器HTML。

document.getElementById('viewerContainer').outerHTML = '';

或者

container.parentNode.removeChild(container);

谢谢您的回答!不幸的是,内存仍然在增加... - chocolate cake
你尝试过删除$scope.pdfFindController变量吗?我希望它没有保留其他对象实例。 - Giovazz89
我尝试了$scope.pdfFindController = nulldelete $scope.pdfFindController,但都没有成功... nullundefined之间可能有什么差异吗? - chocolate cake
不应该:通过首先执行“delete”,您会破坏对象属性,然后立即将其设置为“null”或“undefined”,变量将被完全清除...但是您说您在单独的视图中呈现文件:它是弹出窗口还是单独的窗口?然后,在关闭之前必须运行它(甚至在开始所有内容之前删除HTML元素,然后清除JS对象)。 - Giovazz89

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接