We have updated Flexmonster Software License Agreement, effective as of September 30, 2024. Learn more about what’s changed.

FlexmonsterPivot memory leak

Answered
Claudio Raggio asked on December 22, 2023

Hi, while checking the performance of my application I noticed that the FlexmonsterPivot component is not cleared during the destruction of the host component resulting in memory leak.
Maybe I'm doing something wrong or do I need to do some explicit dispose call to clean up the heap?
I tried with a trivial example, and navigating between this component and my home page creates the memory leak that you can see in the attached screenshot.
Here my very simple markup and my ts, thanks in advance 4 any suggestions.

  <fm-pivot
  *ngIf="showPivot"
  #pivot
  [report]="pivotReport"
  [toolbar]="true"
  [height]="'100%'"
  [width]="'100%'"
  licenseKey="****-****-***-****"
 
>
</fm-pivot>

 
 

import { HttpClient } from "@angular/common/http";
import { Component, OnInit } from "@angular/core";
import { lastValueFrom } from "rxjs";

@Component({
  selector: "app-pivot-sandbox",
  templateUrl: "./pivot-sandbox.component.html",
  styleUrls: ["./pivot-sandbox.component.scss"],
})
export class PivotSandboxComponent implements OnInit {
  showPivot = false;
  pivotReport: Flexmonster.Report;

  constructor(private httpClient: HttpClient) {}

  ngOnInit(): void {
lastValueFrom(this.httpClient
  .get("assets/temp/sandbox.json"))
  .then((res: object[]) => {
this.pivotReport = {};

this.pivotReport.dataSource = {
  mapping: {
Quantity: {
  type: "number"
},
Price: {
  type: "number"
},
"Retail Category": {
  type: "string"
},
Sales: {
  type: "number"
},
"Order Date": {
  type: "year/quarter/month/day"
},
Date: {
  type: "date"
},
Status: {
  type: "string"
},
"Product Code": {
  type: "string"
},
Phone: {
  type: "string"
},
Country: {
  type: "string",
  dimensionUniqueName: "Location",
  filters: false
},
City: {
  type: "string",
  dimensionUniqueName: "Location"
},
CurrencyID: {
  type: "property",
  hierarchy: "Country"
},
"Contact Last Name": {
  type: "string"
},
"Contact First Name": {
  type: "string"
},
"Deal Size": {
  type: "string"
}
  },
  data: res
}

this.pivotReport.slice = {};
this.pivotReport.slice.reportFilters = [
  {
uniqueName: "Date.Year",
filter: {
  members: ["date.year.[2019]"],
},
  },
  {
uniqueName: "Date.Month",
  },
];
this.pivotReport.slice.rows = [
  {
uniqueName: "Country",
filter: {
  members: [
"Country.[australia]",
"Country.[switzerland]",
"Country.[norway]",
"Country.[uk]",
"Country.[sweden]",
"Country.[ukraine]",
"Country.[israel]",
"Country.[denmark]",
"Country.[usa]",
"Country.[canada]",
"Country.[poland]",
  ],
},
  },
  {
uniqueName: "Retail Category",
filter: {
  members: [
"retail category.[books & movies]",
"retail category.[cellphones & accessories]",
"retail category.[health & personal care]",
  ],
},
  },
  {
uniqueName: "City",
  },
];
this.pivotReport.slice.columns = [
  {
uniqueName: "Order Date",
filter: {
  members: ["order date.[2019]", "order date.[2018]"],
},
  },
  {
uniqueName: "[Measures]",
  },
];
this.pivotReport.slice.measures = [
  {
uniqueName: "Price",
aggregation: "sum",
format: "-13w0a1w1c23j00"
  }
];
this.pivotReport.slice.sorting = {
  column: {
type: "desc",
tuple: [],
measure: {
  uniqueName: "Price",
  aggregation: "sum"
}
  }
};

this.showPivot = true;
  });
  }
}

Attachments:
mleak.PNG

5 answers

Public
Maksym Diachenko Maksym Diachenko Flexmonster December 22, 2023

Hello, Claudio!

Thank you for reaching out to us.

Please note that we take memory management within Flexmonster very seriously. With this in mind, Flexmonster provides a dedicated dispose() method, that removes the component from a page and clears up the used memory. This method was implemented to maximize memory optimization, and regular performance tests are run on our side to ensure its functioning. We suggest explicitly calling the dispose() method when the host component is destroyed.

Please let us know if our recommendation helped to optimize memory usage.

Best Regards,
Maksym

Public
Claudio Raggio December 22, 2023

Thanks for the help, it works perfectly!
I had no doubts about your care regarding memory, in fact I supposed I had to call an explicit method.
Just a curiosity: why isn't the dispose method called automatically inside the ngOnDestroy of the Angular FlexmonsterPivot component?
Thanks again,
C

Public
Maksym Diachenko Maksym Diachenko Flexmonster December 22, 2023

Hello, Claudio!

Thank you for your quick response.
We are glad to hear that the dispose() method helped you. Speaking of automatic disposal for our Angular wrapper, we agree that this may be helpful, and this idea sounds reasonable to us. Our team will research the possibility of adding an automatic call of the dispose() API call in the ngOnDestroy lifecycle hook. We will return to you with the results, ETA Jan 9th, 2024.
Feel free to contact us if further questions arise.

Best Regards,
Maksym

Public
Maksym Diachenko Maksym Diachenko Flexmonster January 8, 2024

Hello, Claudio,

We are glad to inform you that the implementation of the ngOnDestroy method was added to the ng-flexmonster wrapper. This is available in the 2.9.68 version of Flexmonster: https://www.flexmonster.com/release-notes/version-2-9-68/ 
You are welcome to update the component: https://www.flexmonster.com/doc/updating-to-the-latest-version/  

Looking forward to hearing your feedback.

Best Regards,
Maksym

Public
Maksym Diachenko Maksym Diachenko Flexmonster January 30, 2024

Hello, Claudio!

Hope you are doing well.
Our team is wondering if you had time to update the ng-flexmonster wrapper. Please let us know if the update helped you to resolve the memory issues.

Best Regards,
Maksym

Please login or Register to Submit Answer