Почему InlineShape.add в Word2013 приводит к утечке памяти - PullRequest
0 голосов
/ 16 апреля 2019

Моя программа должна добавить фотографии в таблицу Word Document. Столкнулся с тем, что в Word 2013 программа работает намного медленнее или даже зависает. Я начал искать проблемные области, и кажется, что проблема в памяти занята при добавлении изображений.

Я добавляю изображения в таблицу Word 2013 методом InlinesShapes.AddPicture. после этого используемая память увеличивается на ~ 50 МБ для каждого изображения. Когда он достигает ~ 600 МБ, он прекращает расти с такой скоростью, и рост составляет около 1 МБ. Затем в какой-то момент Word очищает память до 200 и снова и снова.

Но если я сделаю то же самое в Word 2007, то объем заблокированной памяти будет меньше 1 КБ за все время.

Word 2007 на моем ноутбуке (Win 8.1, i5-4300u), Word 2013 устанавливается на другой компьютер (Virtual Desktop с Win 7, Xeon E5) - если это имеет значение.

Я добавляю обычные фотографии, сделанные с помощью камеры, например: 4160x3120, 72 точек на дюйм, 24 бита, размер 500 Кб, JPG.

Этот пример кода с вычислением используемой памяти

Sub A()  
    ' >-- SOME CODE --<

    Dim objCell As Word.Cell
    'user method that return first free Word.Cell from table
    Set objCell = TableManager.Get_FreeCell(objTable) 
    'clear
    Tools.MemCheck "<- mem before paste"

    objCell.Range.InlineShapes.AddPicture sFilePath 

    'clear
    Tools.MemCheck "-> mem after paste"

    ' >-- SOME CODE --<

    Set objCell = Nothing
 End Sub

Вывод по Word2013

    296.156 Mb <- mem before paste
    345.793 Mb -> mem after Paste
    346.504 Mb <- mem before paste
    396.18  Mb -> mem after Paste

Вывод по Word2007

    109.867 Mb <- mem before paste
    109.871 Mb -> mem after Paste
    109.871 Mb <- mem before paste
    109.879 Mb -> mem after Paste
    109.887 Mb <- mem before paste
    109.887 Mb -> mem after Paste

Есть код MemCheck. Объявил mobjSWbemServices глобальным, чтобы исключить его из проблемы.

Dim mobjSWbemServices as Object
Sub MemCheck(Optional ByVal sDescription As String = vbNullString)
    If mobjSWbemServices is nothing then Set mobjSWbemServices = GetObject("winmgmts:")
    Dim GetMemUsage As Double
     GetMemUsage = mobjSWbemServices.Get( _
        "Win32_Process.Handle='" & _
        GetCurrentProcessId & "'").WorkingSetSize / 1024 / 1024    

    Debug.Print Round(GetMemUsage, 3); " Mb"; vbTab; sDescription
   'GetCurrentProcessId  is Declared Library: 
     'Private Declare PtrSafe Function GetCurrentProcessId Lib "kernel32" () As Long
     'Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
End Sub

Так в чем может быть проблема? Я что-то не так делаю или это ошибка, и мне нужно установить некоторые обновления?

1 Ответ

0 голосов
/ 18 апреля 2019

Произошло серьезное изменение в графическом движке, используемом между Word 2007 (и 2010) и Word 2013 (и более поздними версиями). Это может быть фактором. Также факт, что объектная модель медленнее в Word 2013 (и более поздних версиях), отчасти по соображениям безопасности, насколько я помню. Так что, возможно, вы не сможете сделать многое.

Одна вещь, которую вы можете попробовать, - это очистить стек Word в UNDO и явно СОХРАНИТЬ документ. Это уменьшит количество объектов, которыми управляет Word для поддержки Undo, и может ускорить процесс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...