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
[TIMOB-25693] Android: Possible memory leak when setting ListSections on a ListView #9784
Conversation
@jquick-axway Bump. |
@@ -1088,6 +1088,7 @@ public void release() | |||
|
|||
public void releaseViews() | |||
{ | |||
release(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is necessary, releaseViews
should only remove the reference to the listView
. If release
needs calling it should be done separately
|
||
// Release current sections in the lest | ||
for (ListSectionProxy listSectionProxy : this.sections) { | ||
listSectionProxy.release(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should be releaseViews()
?
If we release the whole proxy then we can't re-add it again later
@ypbnv ,Can you please look at the suggested changes by @garymathews . |
Generated by 🚫 dangerJS |
@garymathews @lokeshchdhry The proposed changes are correct, but not enough to eliminate the memory leak. I have been working on it, but so far I haven't been able to get it done. The sample application keeps references to I will update you once I have something working or at least in the right direction. I am not sure if we should keep it with a 7.1.0 milestone, though. It is hard for me to give an ETA. |
bef6adc
to
57fd61a
Compare
@garymathews Thank you for solving this! |
if (proxySupport != null) { | ||
proxySupport.onEventFired(event, data); | ||
if (proxySupport != null && proxySupport.get() != null) { | ||
proxySupport.get().onEventFired(event, data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a race condition here where the weak reference can be collected between the 2 get()
calls. It's slim, but it can happen. The following would solve it.
KrollProxySupport proxy = (proxySupport != null) ? proxySupport.get() : null;
if (proxy != null) {
proxy.onEventFired(event, data);
}
Not trying to be picky here, but I've seen Java code get burned by issues like this in the past. We should do the same in the setHasListenersForEventType()
method.
|
||
for (ListSectionProxy listSectionProxy : this.sections) { | ||
listSectionProxy.releaseViews(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question:
Calling releaseViews()
will release the section. Will this put the JavaScript ListSection
object in a bad state and prevent the developer from re-adding the section to the ListView
?
Here's another test case: const NUM_SECTIONS = 50, NUM_ITEMS_PER_SECTION = 100;
var win = Ti.UI.createWindow({backgroundColor: 'white'}),
listView = Ti.UI.createListView({
templates: {
template: {
childTemplates: [
{
type: 'Ti.UI.Label',
bindId: 'label',
properties: {
color: 'black'
}
}
]
}
},
defaultItemTemplate: 'template'
}),
fillListView = Ti.UI.createButton({ title: 'FILL', bottom: 5, left: 5 }),
clearListView = Ti.UI.createButton({ title: 'CLEAR', bottom: 5, right: 5 }),
sections = [];
function populateSections () {
sections = [];
for (let i = 0; i <= NUM_SECTIONS; i++) {
let section = Ti.UI.createListSection({ headerTitle: `SECTION #${i + 1}` }),
items = [];
for (let j = 0; j <= NUM_ITEMS_PER_SECTION; j++) {
items.push({ label: { text: `ITEM ${j + 1}` } });
}
section.setItems(items);
sections.push(section);
}
}
fillListView.addEventListener('click', function () {
populateSections();
listView.setSections(sections);
// lets test re-adding sections
listView.setSections([]);
listView.setSections(sections);
});
clearListView.addEventListener('click', function () {
sections = [];
listView.setSections(sections);
});
win.add([ listView, fillListView, clearListView ]);
win.open(); |
c6baa2d
to
4439d83
Compare
FR Passed. Current sections are released when repopulating & there does not seen to be a memory leak & the app does not crash due to out of memory issues. Studio Ver: 5.0.0.201712081732 |
it seem like not resolve ,i test in android 7.1.2 if a window has a listview with 2 section, open it ,close it(exit the app), and, Views num related to sections.length, i test with: 6.3.0.GA,7.2.0,7.1.x, my own build 7.1.x, ypbnv/titanium_mobile , all leak, my app.js,no listview.setSections(xyz) var win = Ti.UI.createWindow({backgroundColor: 'white'}); var fruitSection = Ti.UI.createListSection({ headerTitle: 'Fruits'}); var vegSection = Ti.UI.createListSection({ headerTitle: 'Vegetables'}); listView.sections = sections; |
we are still having this issue, the original fix posted before the requested changes seemed to work when we tested them locally, but 7.1.0 GA still leaks |
JIRA: https://jira.appcelerator.org/browse/TIMOB-25693
Optional Description:
Release current section items when repopulating a list through
setSection()
.Test case:
Alloy application in the JIRA ticket.
Clicking multiple times on Open List and/or Repopulate list should not crash the application.