As many of you might now, yesterday the new version of Monotouch was released and it includes a very useful and much needed memory profiler. I'm using it to fine tune my app. What I am trying now, is to make sure that the reference count is not increasing constantly on any of my objects.
So my question to any monotouch/cocoa gurus is this: Let's say I have a child UIViewController that I regularly present through my main view controller. If the reference count for the child view controller is constantly 1 even after I repeat the process of presenting it and hiding it a few times, does this mean I am out of the woods?
In other words, is this the only thing I should take care of in order to allow monotouch/ios to do proper garbage collection and not hog the device's memory? I am asking because the TOTAL MEMORY as reported in the profiler is increased with each presentation, even though the reference count of the child view controller does not increase.
The child view controller uses a lot of UIImage, loaded with UIImage.FromBundle
Thanks in advance
The problem is likely UIImage.FromBundle. This method will cache the image for the lifetime of the application (which seems to match your description of how memory just increases).
Related
I've been trying to resolve this problem for a while now, I even gave it a shot to rewrite the entire program but without success. The application is running on VueJS 2.3.3 and is supposed to be running on Chromium in combination with a Raspberry Pi (irrelevant information, for now).
We're working with several components which are being included in a single file, later on this file will be compiled using either gulp or npm run dev. When the instance of VueJS initializes, a request will be send using Vue Resource's $http option. This'll receive a json response with a size of around 30mb. This'll be saved in the data array, as seen here:
this.$http.get('<url>' + this.token)
.then((response) => {
this.properties = response.properties;
});
This data will later on be used for further actions, another thing that is worth mentioning is that the data is being refreshed every once in a while. Which is where I think the problem occurs, if I'm not refreshing the data every 5 minutes (can be longer too, really depends on the way I'm testing) the program runs fine. It's just that I want to refresh the data every once in a while to retrieve new information. The way of setting a timeout which I'm using is as following:
this.dataTimeout = setTimeout(this.refreshData, 300000);
Each (so called) property has at least 6 base64 images saved in it's JSON, which are later used to present to the user. Besides that, there is a name, address, and some other tiny bits of data. It doesn't sound all that wrong but I'm getting the feeling that each response makes the memory grow so intense that even a desktop is getting trouble running it.
Each 10 seconds a new property will be presented on the user's screen including the images, street, location, etc. I'm not sure if there is a memory leak in my code or if I'm forgetting something. A few questions pop up in my head:
Do I need to reset the response I'm getting from the server back to
null or undefined?
Could there be a leak in one of the plugins I'm using (Just VueResources)?
For how long can a VueJS instance stay alive, is there any recommended time to reload the entire program?
What thinks should I take in consideration in order to achieve this at all?
I've taken out the data renewal and put a demo project online, this can be seen right here. The main problem I'm having is that the browser just runs out of memory and shows us the amazing Aw snap! page from Chrome. I tried taking snapshots from the memory usage but it all seems fine, it just explodes randomly after a while.
Well, I don't know what really does your app, but are your 30Mb of data really useful / essential ? In JSON moreover ?
Maybe you don't need all this data, and you could just adapt the data to your needs. For example, keep your JSON store data, and retrieve your Base64 images by another way.
I don't understand why you store in memory images. Images are just useful for display purpose in my opinion.
So I think 30Mb is really huge. But maybe I'm wrong ?
By the way, I've tested with Firefox Nightly, no problem here. Doesn't seem to crash. Maybe I don't encounter the refresh call ?
I am suffering from a memory leap within my WP8 app.
I have investigated and narrowed the problem down though I would like some guidance on where to go next.
I do have a hunch that the Pivot and LongListSelector are the cause, described below.
Problem Description:
App browses across numerous pages (typically a few dozen).
Memory use is increasing by around 2-4MB per page and not being fully released.
After around 25 pages memory use has increased from 30MB to 90MB.
Existing Code:
I am already performing some cleanup on each page before navigating to the next.
I am also already calling NavigationService.RemoveBackEntry() to keep the Back Stack small.
Investigation:
I have used the Memory Profiler which reveals about 15MB of the growth is my own data that isn't being cleaned up.
The remaining 40-50MB is not included in the Heap Summary (i.e. the total only comes to about 15MB out of the observed 90MB).
I will work on the 15MB, but since it doesn't appear to be the most significant factor, I would like some guidance on sensible next steps.
Possible Cause:
I have another set of pages (again typically a few dozen pages when browsed) composed of very similar content.
These pages however do NOT show the same problem. Memory use remains low throughout.
Both sets of pages use similar cleanup code when navigating.
One key difference is the affected pages use a Pivot control, each of which has a 3 or 4 Pivot Items, a couple of which contain LongListSelectors.
The LongListSelectors are data bound to Generic Lists generated at run time. No images, only text. Not especially long lists, 20 or so items in each.
I have come across a couple of posts vaguely suggesting that this combination of controls is susceptible to memory leaks.
I commented the code that populates these controls, and sure enough, memory use now peaks at around 50-60MB.
It may be even lower if I remove the controls completely (I haven't tested that yet).
So, these controls are not the whole story, but clearly are a large part of the problem.
Question:
Is there a known issue with these controls (LongListSelector, Pivot)?
Should there be some code used to clean up these controls? I have tried setting the list ItemSource to an empty list, but this had no effect on the memory growth.
Is there any way to workaround it? (obviously changing the type of controls used is one option).
Thanks for reading.
After some investigation, I have found what looks like a problem with the LongListSelector recovering memory when it is cleaned up.
I have posted more details and a workaround here:
http://cbailiss.wordpress.com/2014/01/24/windows-phone-8-longlistselector-memory-leak/
I had a same problem. All I did just changed source List<>s to ObservableCollection<>s, and then on SelectedItem changing I clearing source collection which is not visible at the moment.
I was wondering how does Google Chrome works in regards to its multiprocess architecture. From what I understand there is one process which renders everything and every page has one additional process associated with it. My question is, if a page loads 100MB picture how does it pass it to the renderer process?
In other words, what is the fastest way to pass (copy?) data from one process to another?
In yet another words, if one process produces 100 MB of data, how to let another process to read it? (Note that the data was produces after the process forked).
Edit: If the child process creates the data and the parent process doesn't know in advance the size of the data, how to pass the data from child to parent? I mean, "shared block of memory" has to created by the parent, right? So how much does the parent know how much of space to allocate?
General name for this is IPC - Inter Process Communication.
http://en.wikipedia.org/wiki/Inter-process_communication
Now I do not know how chrome implements it but I hope you get the idea. If I had to choose one I'd say memory sharing or pipe but it could be (almost) any of those.
have developed a touch screen stand alone application. The interactive is currently running 10 - 13 hours per day. If the user interacts with interactive the memory level is going on increasing. The interactive has five screens while travelling through each screen I have removed the movieclip, assets, listener's and I set objects to null. Yet the memory level keep increasing.
Also I have used third party tool "gskinner" to solve this problem, It improves the result even though some memory leakage is there.
Please help me, thanks in advance.
Your best results will come from writing the code in a way that elements are properly garbage collected on removal. That means removing all the objects, listeners and MovieClips/Sprites within that are no longer used.
When I'm trying to get this stuff done quickly, I've been using casalib's CasaMovieClip and CasaSprite instead of regular MovieClips and Sprites. The reason is that they have the destroy() functions as well as some other functions that help you garbage collect easily.
But the best advice I can give is to read up on garbage collection. Grant Skinner's blog is a great place to start.
Also, check for setTimeout() and dictionaries, as these can cause leaks as well if not used properly.
What's the best lifetime model for a DataContext? Should I just create a new one whenever I need it (aka, function level), should I keep one available in each class that would use it (class level), or should I create a static class with a static DataContext (app-domain level)? Are there any considered best practices on this?
You pretty much need to keep the same data context available throughout the lifetime of the operations you want to perform if you're ever going to be storing changes which are to be .SubmitChanges()'d later, as otherwise you will lose those changes.
If you're just querying stuff then it's fine to create them as needed, but then if later you want to .SubmitChanges() you'll have to refactor your code a lot, so you may as well adopt the pattern of effectively keeping the datacontext global throughout your app from the beginning.
Note the data context is disconnected. The connection is only made when the query data is enumerated (not when you first run the query, it's a 'lazy' data type so only provides data when it's needed), and then closed immediately afterwards. On .SubmitChanges() the connection is opened to submit the changes then closed immediately afterwards. So don't think keeping the datacontext around keeps a connection open, it doesn't (you can hook the StateChange event of the connection to confirm this for yourself, that's how I'm sure).
There is a great article over at Rick Strahl's Blog which covers this topic in depth, far more than my answer here provides!!
I think Jeff Atwood talked about this in the Herding Code podcast, when he was questioned about the exact same thing. Listen to it towards the last 15-20 minutes or so.
I think in SO, the datacontext is created in the Controller class. Not sure about a lot of details here. But that's what it looked like.