Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory leak in C3 charts when navigating on to and off of VM details #1031

Closed
bond95 opened this issue Jun 5, 2019 · 7 comments · Fixed by #1048
Closed

Memory leak in C3 charts when navigating on to and off of VM details #1031

bond95 opened this issue Jun 5, 2019 · 7 comments · Fixed by #1048
Labels
Priority: High Work on these first

Comments

@bond95
Copy link
Contributor

bond95 commented Jun 5, 2019

It seems I have the reproduction steps:

  1. have running VM
  2. check browser console, go back to VM detail
  3. Shutdown with Force (normal shutdown seems to work)
  4. Run VM again
  5. go to browser console, wait a while
  6. when going back to VM detail, charts already loaded
  7. go to browser console, back to detail
  8. charts broken

It doesn't happen 100%, but mostly. Reproduced in Google Chrome 74.0 and also Firefox 66.0

Originally posted by @leistnerova in #956 (comment)

@sjd78
Copy link
Member

sjd78 commented Jun 5, 2019

Originally posted in #956 (comment)

I tested Chrome 74.0 on Mac against the web-ui dev server and against web-ui installed to my dev ovirt-engine and was able to reproduce the c3 no charts problem and the browser tab crashing problem. The tab appears to crash because of a massive memory leak. I also tested with Firefox on fedora against my dev ovirt-engine with web-ui installed and recreated the memory leak there. Firefox's tab doesn't crash as politely as the Chrome tab.

Here is a video of the Chrome 74.0 on Mac C3 fail followed by memory leak and tab crash:
https://youtu.be/ZrOGGyPQpPA

@sjd78 sjd78 changed the title Memory leak in C3 charts Memory leak in C3 charts when navigating betwen VM details and VM webvnc consle Jun 5, 2019
@sjd78
Copy link
Member

sjd78 commented Jun 5, 2019

Originally posted in #956 (comment)

@leistnerova thanks! @sjd78 does the console code terminate properly when VM is shut down? if not...could be novnc bug or our code around it. Generally as soon as VM is down the console should die with it.

Console code must be terminated with VmConsole component. When user go to detail page from console page, VmConsole is unmounting and console terminate as well. According to my experiments problem can be in charts, because this bug cause frequent update of charts, which can be cause of growing memory usage.

In my testing of this issue, I never had to change the running state of the VM. I only had to swap back and forth between the webvnc console and the VM details page. I doubt the VM's actual console or running state change has a direct impact on this issue.

@sgratch sgratch added the Priority: High Work on these first label Jun 5, 2019
@sjd78 sjd78 changed the title Memory leak in C3 charts when navigating betwen VM details and VM webvnc consle Memory leak in C3 charts when navigating on to and off of VM details Jun 6, 2019
@bond95
Copy link
Contributor Author

bond95 commented Jun 6, 2019

Logs from Dev Tools

c3.js:9223 Uncaught TypeError: Cannot read property 'data_types' of null
    at ChartInternal.c3_chart_internal_fn.isPieType (c3.js:9223)
    at ChartInternal.c3_chart_internal_fn.isArcType (c3.js:9234)
    at ChartInternal.c3_chart_internal_fn.getArc (c3.js:4473)
    at c3.js:4816
    at SVGPathElement.<anonymous> (d3.js:8775)
    at Object.tick [as c] (d3.js:8956)
    at d3_timer_mark (d3.js:2166)
    at d3_timer_step (d3.js:2147)
c3_chart_internal_fn.isPieType @ c3.js:9223
c3_chart_internal_fn.isArcType @ c3.js:9234
c3_chart_internal_fn.getArc @ c3.js:4473
(anonymous) @ c3.js:4816
(anonymous) @ d3.js:8775
tick @ d3.js:8956
d3_timer_mark @ d3.js:2166
d3_timer_step @ d3.js:2147
requestAnimationFrame (async)
d3_timer_step @ d3.js:2156
requestAnimationFrame (async)
d3_timer_step @ d3.js:2156
requestAnimationFrame (async)
d3_timer_step @ d3.js:2156
requestAnimationFrame (async)
d3_timer_step @ d3.js:2156
requestAnimationFrame (async)
d3_timer_step @ d3.js:2156
requestAnimationFrame (async)
d3_timer_step @ d3.js:2156
requestAnimationFrame (async)
d3_timer_step @ d3.js:2156
requestAnimationFrame (async)
d3_timer_step @ d3.js:2156
requestAnimationFrame (async)
d3_timer_step @ d3.js:2156
requestAnimationFrame (async)
d3_timer @ d3.js:2142
d3_transitionNode @ d3.js:8966
d3_selectionPrototype.transition @ d3.js:8638
c3_chart_internal_fn.showTargets @ c3.js:1488
c3_chart_internal_fn.updateTargets @ c3.js:1482
c3_chart_internal_fn.load @ c3.js:6141
c3_chart_internal_fn.loadFromArgs @ c3.js:6163
c3_chart_fn.load @ c3.js:4037
loadNewData @ react-c3js.js:74
updateChart @ react-c3js.js:92
componentWillReceiveProps @ react-c3js.js:49
callComponentWillReceiveProps @ react-dom.development.js:11413
updateClassInstance @ react-dom.development.js:11605
updateClassComponent @ react-dom.development.js:13045
beginWork @ react-dom.development.js:13715
performUnitOfWork @ react-dom.development.js:15741
workLoop @ react-dom.development.js:15780
renderRoot @ react-dom.development.js:15820
performWorkOnRoot @ react-dom.development.js:16437
performWork @ react-dom.development.js:16358
performSyncWork @ react-dom.development.js:16330
requestWork @ react-dom.development.js:16230
scheduleWork$1 @ react-dom.development.js:16096
enqueueSetState @ react-dom.development.js:11185
Component.setState @ react.development.js:273
onStateChange @ connectAdvanced.js:222
notify @ Subscription.js:30
notifyNestedSubs @ Subscription.js:69
onStateChange @ connectAdvanced.js:219
notify @ Subscription.js:30
notifyNestedSubs @ Subscription.js:69
onStateChange @ connectAdvanced.js:219
notify @ Subscription.js:30
notifyNestedSubs @ Subscription.js:69
onStateChange @ connectAdvanced.js:219
dispatch @ redux.js:227
e @ VM26:1
(anonymous) @ middleware.js:72
(anonymous) @ middleware.js:25
dispatch @ redux.js:569
(anonymous) @ utils.js:265
(anonymous) @ proc.js:500
exec @ scheduler.js:25
flush @ scheduler.js:66
asap @ scheduler.js:39
runPutEffect @ proc.js:497
runEffect @ proc.js:446
next @ proc.js:326
currCb @ proc.js:399
checkEffectEnd @ proc.js:623
chCbAtKey @ proc.js:638
currCb @ proc.js:399
end @ proc.js:367
task.cont @ proc.js:110
next @ proc.js:332
currCb @ proc.js:399
end @ proc.js:367
task.cont @ proc.js:110
next @ proc.js:332
currCb @ proc.js:399
mightThrow @ jquery.js:3583
process @ jquery.js:3651
setTimeout (async)
(anonymous) @ jquery.js:3689
fire @ jquery.js:3317
fireWith @ jquery.js:3447
fire @ jquery.js:3455
fire @ jquery.js:3317
fireWith @ jquery.js:3447
mightThrow @ jquery.js:3642
process @ jquery.js:3651
setTimeout (async)
(anonymous) @ jquery.js:3689
fire @ jquery.js:3317
fireWith @ jquery.js:3447
fire @ jquery.js:3455
fire @ jquery.js:3317
fireWith @ jquery.js:3447
mightThrow @ jquery.js:3642
process @ jquery.js:3651
setTimeout (async)
(anonymous) @ jquery.js:3689
fire @ jquery.js:3317
fireWith @ jquery.js:3447
fire @ jquery.js:3455
fire @ jquery.js:3317
fireWith @ jquery.js:3447
done @ jquery.js:9272
(anonymous) @ jquery.js:9514
load (async)
send @ jquery.js:9533
ajax @ jquery.js:9173
httpGet @ transport.js:71
snapshotNics @ index.js:284
runCallEffect @ proc.js:524
runEffect @ proc.js:446
next @ proc.js:326
proc @ proc.js:281
resolveIterator @ proc.js:467
runEffect @ proc.js:443
next @ proc.js:326
proc @ proc.js:281
resolveIterator @ proc.js:467
runCallEffect @ proc.js:528
runEffect @ proc.js:446
(anonymous) @ proc.js:655
runAllEffect @ proc.js:654
runEffect @ proc.js:446
next @ proc.js:326
currCb @ proc.js:399
checkEffectEnd @ proc.js:623
chCbAtKey @ proc.js:638
currCb @ proc.js:399
end @ proc.js:367
task.cont @ proc.js:110
next @ proc.js:332
currCb @ proc.js:399
end @ proc.js:367
task.cont @ proc.js:110
next @ proc.js:332
currCb @ proc.js:399
mightThrow @ jquery.js:3583
process @ jquery.js:3651
setTimeout (async)
(anonymous) @ jquery.js:3689
fire @ jquery.js:3317
fireWith @ jquery.js:3447
fire @ jquery.js:3455
fire @ jquery.js:3317
fireWith @ jquery.js:3447
mightThrow @ jquery.js:3642
process @ jquery.js:3651
setTimeout (async)
(anonymous) @ jquery.js:3689
fire @ jquery.js:3317
fireWith @ jquery.js:3447
fire @ jquery.js:3455
fire @ jquery.js:3317
fireWith @ jquery.js:3447
mightThrow @ jquery.js:3642
process @ jquery.js:3651
setTimeout (async)
(anonymous) @ jquery.js:3689
fire @ jquery.js:3317
fireWith @ jquery.js:3447
fire @ jquery.js:3455
fire @ jquery.js:3317
fireWith @ jquery.js:3447
done @ jquery.js:9272
(anonymous) @ jquery.js:9514
load (async)
send @ jquery.js:9533
ajax @ jquery.js:9173
httpGet @ transport.js:71
snapshotDisks @ index.js:280
runCallEffect @ proc.js:524
runEffect @ proc.js:446
next @ proc.js:326
proc @ proc.js:281
resolveIterator @ proc.js:467
runEffect @ proc.js:443
next @ proc.js:326
proc @ proc.js:281
resolveIterator @ proc.js:467
runCallEffect @ proc.js:528
runEffect @ proc.js:446
(anonymous) @ proc.js:655
runAllEffect @ proc.js:654
runEffect @ proc.js:446
next @ proc.js:326
currCb @ proc.js:399
checkEffectEnd @ proc.js:623
chCbAtKey @ proc.js:638
currCb @ proc.js:399
end @ proc.js:367
task.cont @ proc.js:110
next @ proc.js:332
currCb @ proc.js:399
end @ proc.js:367
task.cont @ proc.js:110
next @ proc.js:332
currCb @ proc.js:399
mightThrow @ jquery.js:3583
process @ jquery.js:3651
setTimeout (async)
(anonymous) @ jquery.js:3689
fire @ jquery.js:3317
fireWith @ jquery.js:3447
fire @ jquery.js:3455
fire @ jquery.js:3317
fireWith @ jquery.js:3447
mightThrow @ jquery.js:3642
process @ jquery.js:3651
setTimeout (async)
(anonymous) @ jquery.js:3689
fire @ jquery.js:3317
fireWith @ jquery.js:3447
fire @ jquery.js:3455
fire @ jquery.js:3317
fireWith @ jquery.js:3447
mightThrow @ jquery.js:3642
process @ jquery.js:3651
setTimeout (async)
(anonymous) @ jquery.js:3689
fire @ jquery.js:3317
fireWith @ jquery.js:3447
fire @ jquery.js:3455
fire @ jquery.js:3317
fireWith @ jquery.js:3447
done @ jquery.js:9272
(anonymous) @ jquery.js:9514
load (async)
send @ jquery.js:9533
ajax @ jquery.js:9173
httpGet @ transport.js:71
snapshotNics @ index.js:284
runCallEffect @ proc.js:524
runEffect @ proc.js:446
next @ proc.js:326
proc @ proc.js:281
resolveIterator @ proc.js:467
runEffect @ proc.js:443
next @ proc.js:326
proc @ proc.js:281
resolveIterator @ proc.js:467
runCallEffect @ proc.js:528
runEffect @ proc.js:446
(anonymous) @ proc.js:655
runAllEffect @ proc.js:654
runEffect @ proc.js:446
next @ proc.js:326
currCb @ proc.js:399
checkEffectEnd @ proc.js:623
chCbAtKey @ proc.js:638
currCb @ proc.js:399
end @ proc.js:367
task.cont @ proc.js:110
next @ proc.js:332
currCb @ proc.js:399
end @ proc.js:367
task.cont @ proc.js:110
next @ proc.js:332
currCb @ proc.js:399
end @ proc.js:367
task.cont @ proc.js:110
next @ proc.js:332
currCb @ proc.js:399
mightThrow @ jquery.js:3583
process @ jquery.js:3651
setTimeout (async)
(anonymous) @ jquery.js:3689
fire @ jquery.js:3317
fireWith @ jquery.js:3447
fire @ jquery.js:3455
fire @ jquery.js:3317
fireWith @ jquery.js:3447
mightThrow @ jquery.js:3642
process @ jquery.js:3651
setTimeout (async)
(anonymous) @ jquery.js:3689
fire @ jquery.js:3317
fireWith @ jquery.js:3447
fire @ jquery.js:3455
fire @ jquery.js:3317
fireWith @ jquery.js:3447
mightThrow @ jquery.js:3642
process @ jquery.js:3651
setTimeout (async)
(anonymous) @ jquery.js:3689
fire @ jquery.js:3317
fireWith @ jquery.js:3447
fire @ jquery.js:3455
fire @ jquery.js:3317
fireWith @ jquery.js:3447
done @ jquery.js:9272
(anonymous) @ jquery.js:9514
load (async)
send @ jquery.js:9533
ajax @ jquery.js:9173
httpGet @ transport.js:71
getDiskPermissions @ index.js:186
runCallEffect @ proc.js:524
runEffect @ proc.js:446
next @ proc.js:326
proc @ proc.js:281
resolveIterator @ proc.js:467
runEffect @ proc.js:443
next @ proc.js:326
proc @ proc.js:281
resolveIterator @ proc.js:467
runEffect @ proc.js:443
next @ proc.js:326
proc @ proc.js:281
resolveIterator @ proc.js:467
runEffect @ proc.js:443
(anonymous) @ proc.js:655
runAllEffect @ proc.js:654
runEffect @ proc.js:446
next @ proc.js:326
currCb @ proc.js:399
end @ proc.js:367
task.cont @ proc.js:110
next @ proc.js:332
currCb @ proc.js:399
end @ proc.js:367
task.cont @ proc.js:110
next @ proc.js:332
currCb @ proc.js:399
mightThrow @ jquery.js:3583
process @ jquery.js:3651
setTimeout (async)
(anonymous) @ jquery.js:3689
fire @ jquery.js:3317
fireWith @ jquery.js:3447
fire @ jquery.js:3455
fire @ jquery.js:3317
fireWith @ jquery.js:3447
mightThrow @ jquery.js:3642
process @ jquery.js:3651
setTimeout (async)
(anonymous) @ jquery.js:3689
fire @ jquery.js:3317
fireWith @ jquery.js:3447
fire @ jquery.js:3455
fire @ jquery.js:3317
fireWith @ jquery.js:3447
mightThrow @ jquery.js:3642
process @ jquery.js:3651
setTimeout (async)
(anonymous) @ jquery.js:3689
fire @ jquery.js:3317
fireWith @ jquery.js:3447
fire @ jquery.js:3455
fire @ jquery.js:3317
fireWith @ jquery.js:3447
done @ jquery.js:9272
(anonymous) @ jquery.js:9514
load (async)
send @ jquery.js:9533
ajax @ jquery.js:9173
httpGet @ transport.js:71
getVmPermissions @ index.js:191
runCallEffect @ proc.js:524
runEffect @ proc.js:446
next @ proc.js:326
proc @ proc.js:281
resolveIterator @ proc.js:467
runEffect @ proc.js:443
next @ proc.js:326
proc @ proc.js:281
resolveIterator @ proc.js:467
runEffect @ proc.js:443
next @ proc.js:326
currCb @ proc.js:399
end @ proc.js:367
task.cont @ proc.js:110
next @ proc.js:332
currCb @ proc.js:399
end @ proc.js:367
task.cont @ proc.js:110
next @ proc.js:332
currCb @ proc.js:399
mightThrow @ jquery.js:3583
process @ jquery.js:3651
setTimeout (async)
(anonymous) @ jquery.js:3689
fire @ jquery.js:3317
fireWith @ jquery.js:3447
fire @ jquery.js:3455
fire @ jquery.js:3317
fireWith @ jquery.js:3447
mightThrow @ jquery.js:3642
process @ jquery.js:3651
setTimeout (async)
(anonymous) @ jquery.js:3689
fire @ jquery.js:3317
fireWith @ jquery.js:3447
fire @ jquery.js:3455
fire @ jquery.js:3317
fireWith @ jquery.js:3447
mightThrow @ jquery.js:3642
process @ jquery.js:3651
Show 185 more frames

@sjd78
Copy link
Member

sjd78 commented Jun 6, 2019

@bond95 and I just sat to duplicate the issue and we were able to reproduce it consistently in current master (webvnc merged) and in the 1.5.2 release. The issue seems to be localized more around transitioning off of the VM dashboard details page. Web console exaserbates the problem by giving another easy path to transition off of the VM dashboard page.

Steps to reproduce:

  1. Open web-ui
  2. Click in to a VM's details
  3. Click out of the VM details (to either main VM list page or the console page)
  4. Click back on to the VM details
  5. repeat steps 3 & 4 until a c3 error occurs on the browser console (usually 4-8 transitions will do it)

When the charts stop rendering, a memory leak has occurred. The app will continue to function until the c3 charts take too much memory and the browser kills the tab.

@doron-fediuck
Copy link

@sjd78 is there a difference between browsers?
Also, do we have a formal bz opened on this?

@michalskrivanek
Copy link
Member

The only tracker ovirt-web-ui is using is the github issues tracker

@bond95
Copy link
Contributor Author

bond95 commented Jun 17, 2019

@sjd78 is there a difference between browsers?

@doron-fediuck It was tested only on Firefox and Chrome, and there is no difference, it can be reproduced in the same way.

bond95 added a commit to bond95/ovirt-web-ui that referenced this issue Jun 24, 2019
bond95 added a commit to bond95/ovirt-web-ui that referenced this issue Jun 24, 2019
bond95 added a commit to bond95/ovirt-web-ui that referenced this issue Jul 11, 2019
bond95 added a commit to bond95/ovirt-web-ui that referenced this issue Jul 17, 2019
bond95 added a commit to bond95/ovirt-web-ui that referenced this issue Aug 27, 2019
bond95 added a commit to bond95/ovirt-web-ui that referenced this issue Aug 28, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Priority: High Work on these first
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants