vmware: nova compute memory grows continuously with creation and deletions on VMs
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
OpenStack Compute (nova) |
Fix Released
|
Critical
|
Radoslav Gerganov | ||
Icehouse |
Fix Released
|
Undecided
|
Unassigned | ||
VMwareAPI-Team |
New
|
Undecided
|
Unassigned |
Bug Description
nova-compute memory grows to 3gb in a Scaled environment (5000 vm) where continuous VM operations were executed for 72 hours.
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
22181 nova 20 0 3325m 3.0g 6588 R 34.2 19.0 3984:23 nova-compute
To test the memory leak we created and deleted same number of vms for some iterations. Here is the data .
VM Count Memory (KB )
0 516528
20 518520
40 518520
60 522192
80 524068
100 526904
0 526904
20 526904
40 526904
60 526904
80 526904
100 529372
0 530972
20 530972
40 530972
60 530972
80 530972
100 533484
0 533484
20 533484
40 533484
60 533484
80 533484
100 535112
0 535112
When analysed with objgraph, it showed that suds library objects occupied most of the memory.
Changed in nova: | |
importance: | Undecided → High |
Changed in nova: | |
assignee: | nobody → Eric Brown (ericwb) |
Changed in nova: | |
assignee: | Eric Brown (ericwb) → Radoslav Gerganov (rgerganov) |
tags: | added: havana-backport-potential icehouse-backport-potential |
Changed in nova: | |
milestone: | none → juno-1 |
status: | Fix Committed → Fix Released |
tags: | removed: icehouse-backport-potential |
Changed in nova: | |
milestone: | juno-1 → 2014.2 |
The reason for the memory leak is that we use suds objects as keys for the _datastore_ browser_ mapping cache. Suds objects do not implement __eq__ and __hash__ properly for VIM types such as ManagedObjectRe ference, we always have cache miss and thus _datastore_ browser_ mapping grows with every created instance.
This is how it looks like after two spawn() operations:
(Pdb) self._datastore _browser_ mapping er-datastore- 10" rowser" er-datastore- 10" rowser"
{(obj){
value = "datastore-10"
_type = "Datastore"
}: (val){
value = "datastoreBrows
_type = "HostDatastoreB
}, (obj){
value = "datastore-10"
_type = "Datastore"
}: (val){
value = "datastoreBrows
_type = "HostDatastoreB
}}
The solution is to use the 'value' property of the MoRef as we do for the _datastore_ dc_mapping.
I will submit a patch shortly.