Uploaded image for project: 'Magnolia Frontend Helpers'
  1. Magnolia Frontend Helpers
  2. MGNLFE-428

PageEditorBridge listeners create memory leak with Angular Universal SSR

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • Neutral
    • 1.4
    • 1.3.3
    • Angular Renderer
    • None
    • node v16.15.0

    Description

      Steps to reproduce

      1. Clone the spa minimal demos repository: https://git.magnolia-cms.com/scm/demos/minimal-headless-spa-demos.git

      2. Follow the setup instructions for the Angular Universal demo, so that you have a page available at http://localhost:4200/angular-universal-minimal: https://git.magnolia-cms.com/projects/DEMOS/repos/minimal-headless-spa-demos/browse

      3. Restart the SPA with node.js in debug / profiling mode

        1. Stop the `dev:ssr` run

        2. Run the following command from the angular-universal-minimal directory: `node --trace-gc --inspect-brk dist/angular-universal-minimal/server/main.js`

        3. Open Chrome and type `about:inspect` in the address bar

        4. Click the "inspect" link on the remote target `dist/angular-universal-minimal/server/main.js` in the Devices tab

        5. A DevTools window opens for the Node server process

        6. Resume script execution
      4. Load the page (http://localhost:4200/angular-universal-minimal) repeatedly - about 100 times produces a noticeable result


      5. Take a heap snapshot from the DevTools window of the Node server process, in the Memory tab
      6. Expand the `Object` tree branch
        Screenshot of the heap view:

       

      Link to a heap dump: 
      https://drive.google.com/file/d/1LhlKFrPNlWa-lp1psUIqhdF9GxTb4FEk/view?usp=sharing

      Actual results

      • There is one large object in the heap (16 MB for about 100 page loads) containing an array named `updatestate`, which contains callback functions. These function objects each hold a reference to an instance of the Magnolia `EditablePageComponent` as their `this` context.
      • The `updatestate` array grows larger with every Angular Universal render, as callbacks are pushed to it in the constructor of `EditablePageComponent` (delegating to `PageEditorBridge`) but never cleared on Angular destroy events
      • The references to `EditablePageComponent` can retain quite a bit of memory in the heap, as the components hold references to the entire Angular context

        Expected results

      • Objects used for a single Angular Universal render are not retained when the rendering is completed, resp. for the remainder of the server running time
      • The instances of EditablePageComponent are properly garbage collected after an Angular Universal render

        Workaround

      No effective workaround found

      Development notes

      Checklists

        Acceptance criteria

        Attachments

          Issue Links

            There are no Sub-Tasks for this issue.

            Activity

              People

                plequoc Phong Le Quoc
                jc.puja@codify.ch Jean-Christophe Puja
                DeveloperX
                Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved:
                  Work Started:

                  Checklists

                    Bug DoR
                    Task DoD

                    Time Tracking

                      Estimated:
                      Original Estimate - Not Specified
                      Not Specified
                      Remaining:
                      Remaining Estimate - Not Specified
                      Not Specified
                      Logged:
                      Time Spent - 18d 4.5h
                      18d 4.5h