I am in the same situation as the one depicted in this SO question. Indeed my app relies massively on URLImage and also uses SidePanel for navigation. After a while it becomes unusable because of OOM thrown when I press the back button (Android).
So I need advices to avoid these OOM errors. A first advice was given in the above mentionned question, that is to not pass reference to any element from the previous form.
Indeed I was passing the whole form because I wanted to know from where the "generic" next form was called (to know where to go when the user clicks on the back button). So I changed that and now pass the Form's class (myForm.getClass()). However the performance monitor still shows more than 200 MB as "image memory overhead".
So maybe the problem is elsewhere since I need to also pass custom objects. Indeed I have a form A which lists all Reports in an InfiniteScrollAdapter. The Reports are fetched from a server. Then when the user clicks on a row, it opens the selected Report details (date, image, location, ...) in another form (B), and finally if the user clicks on the image or on the location it opens another form with the image in big size or a Google Map of the location.
If it is not possible to pass in those Reports, how can I do, or does the problem really come from these passed in references ?
Any help really appreciated ;-)
I'm guessing you are using problematic images and too many of those without releasing them. A good tool to use is a memory profiler, I use the one in NetBeans which allows you to dig thru the allocation stack and see which code allocates which memory block.
I'd also suggest reading about the various types of images in the developer guide graphics section and the performance section (which discusses memory too). To sum this up make sure your images are sized correctly and are EncodedImage or a variation of those. You might want to unlock() unused encoded images so the GC can act more aggressively on them.
Once you narrow the leak to a specific set of images it should be much easier to give specific advice on how to manage this.
Related
I have a sizable Java app that creates complex data structures describing a drawing, starting with the raw time-stamped data points and displaying the drawing, analyzing it, etc.
When I try to process a series of these drawings, I'm clearly hanging on to memory in the form of a JScrollPane that's used to hold the drawing, but I cannot figure out why. The variable holding the scroll pane is reassigned with each new file loaded, but I noticed that the swing RepaintManager is maintaining a list of the previously displayed panes in its invalidComponents list. This seems then to hang onto the storage for each drawing, and before long I've got 1GB of memory in use when I'm processing files serially and should thus never have more than one drawing's worth of memory in use.
I got a memory dump and have analyzed with the Eclipse memory analyzer and with YourKit.
Here's what I believe to be the smoking gun as displayed by Eclipse's memory analyzer:
Have spent quite a while trying to drill down into this problem. I would be most grateful for any suggestions about where my error may lie or how to work around the problem.
I realize it's difficult to tell without being able to dig into the code, but if there are even any general suggestions/cautions about where to look, that would be great.
As #MadProgrammer suggests, your present code presumably replaces the existing JScrollPane instance:
scrollPane = new JScrollPane(view);
Instead, update the viewport component via setViewportView():
scrollPane. setViewportView(view);
Even better, update the content of view directly. Details would depend on your implementation, but validate() and repaint() represent one approach.
my main activity has over 400 Lines Of Code and contains numerous methods which deals with pdf generations, making the page dynamic, and other condition checks..
i was wondering if i should make it all into different class files.. each specific for its task.. thereby creating at least 3-4 different classes..
so my query is
1) will this approach make the app faster..
2) will this increase the app's size drastically??
also is there anyway to reduce the app's size?
i have deleted all unnecessary pics, xml's & assests..
i just want the size to be below 5mb..
Thanks in advance..
1) No. This won't noticably affect the app's speed.
2) No. The compiled code is actually the smallest part of an APK. Most of the size is caused by resources.
A way to reduce your app's size would be to optimize your compression on the images that are contained in your app. Also, you might be able to draw some of the images in code, as primitives such as lines, circles, squares, depending on what's on the images.
These points may help you :
Java class files increase the app size which you can ignore because it is very very less. So that point you no need to be worried.
As you have mentioned you deleted images and all. Those things actually increase the app size. So delete those as many as possible is not being used.
Creating more classes which will be specific for their purposes, that is OOPs concept and it is very much recommended. So if you want to modify something in future iy will be easy for you find the code as well your code will be modified in that particular class made for that sole pupose.
Hope it will help.
1) will this approach make the app faster?
Faster, can't comment. However, That approach will provide you an opportunity to learn how to make good design and will help you in future maintainability and extension of your project.
2) will this increase the app's size drastically?
Not at all.
I have a game where I draw and move bitmaps over a SurfaceView. The user can interact (drag and drop) these bitmaps. When the player hits the home button then goes back into the game, I want to be able to pause the game, then restore it to where it was before he left it. What is the best way to store my custom objects?
Should I implement onSaveInstanceState(Bundle) and have all of the classes whose objects I want to save implement the Parcelable interface? This would be quite a bit of work, and I'm still not sure how I would save things like bitmaps. I suppose I wouldn't and I would just reload those from disk.
I am also confused about what kind of storage a bundle offers: disk storage that never goes away unless you clear it yourself, or memory storage that goes away if the OS decides to remove your program from memory while it's in the background. According to the comments in this question, it is disk storage. The documentation implies that it is memory storage, saying Note that it is important to save persistent data in onPause(), however I don't find it very clear. This page also implies that it is not persistent: it only lasts as long as the application remains in memory. So which one is it?
The last link above suggests using onRetainNonConfigurationInstance() to keep objects in memory while the application is in the background. This would imply that if the program is taken out of memory by the OS while in the background, everything would be lost. This seems to be what most (all I tested on) games do: if you hit home while playing then go back in, the level resumes. If you hit home, open a lot of stuff (sufficient to make Android remove the game from memory), then go back in, nothing is resumed, the game starts from the main menu. Does that mean this is what they use, and if so, is that a good practice?
Note that the question about a Bundle's persistency is just a secondary curiosity. I don't really care if the state of this game is not permanently saved and can be lost after the game being in the background for a while (as described in 2 above). I'm interested in the best practice for this case.
The basic idea is, IMO, identify the smallest collection of values that will enable you to recreate the state of your game. Save those in shared preferences.
My applications requirement is to contact the webservice, get the xml, parse it and display it using a listfield. I am calling all this classes xmlhandler, objectmodel, displaying it using a lisfield from a class that extends mainscreen which is making my application slow.
Can anyone suggest me how to make it fast?
Is it a apt to popup a loading screen and start a thread for contacting the webservice, get the xml, parsing it and kill the thread, then populate the listscreen and display it?
suggestions of any kind is welcome!
Test the speed of every part of your program. What I usually use is System.nanoTime() and find the difference in time after every part of the program.
Find out which part is slow before you do anything else.
Otherwise, you'll waste a lot of your time on the wrong parts.
For doing this kind of timing work, I often will do internal logging into a StringBuilder, or maybe just into an ArrayList holding raw, unformatted data. After the test is over, I format and output the data. This minimizes the effect of the logging on the timings.
I can only gues so forgive me if I'm wrong - to me it seems more efficient to create the item of list field only when they're really viewed. So I'd try to keep in memory only the parsed strings and create only the UI items currently to be displayed, discard invisible. To make it more smooth you can you can extend it one or more pages before and after current page.
This way the number of displayed items is always constant. You may also add paging to the service layer to limit number of records trabsmitted at once.
I'm trying to write a painting app for a mobile device (Android) that will have a bit more functionality than MS Paint (e.g. various brushes and brush settings, selections, layers) but won't be as complex as Photoshop. I need my app to have a decent undo/redo feature. Unlimited undo/redo is probably not possible. I'd be happy with being able to undo about the last minute worth of user actions (maybe about 20 actions).
The main approaches I know of for undo/redo is:
save the whole state or just the bits that changed after each operation. Undoing involves updating the state by restoring snapshots. Pros: simple to implement Cons: memory intensive.
use the command pattern where each command has a "do action" and "undo action" method. To undo, you just call the undo action of the previous commands. Pros: memory efficient, Cons: much more complex to implement.
My pathological undo/redo scenarios I have to consider is:
the user paints over the whole canvas in one go, where you would want this whole operation to be undone when the user clicks undo. With option 1, we'd need to store a bitmap the size of the whole canvas.
the user draws something, imports image 1.jpg onto the canvas, does some more drawing, 1.jpg is then deleted/modified at some point by another application and then the user wants to undo then redo all their actions in the paint application. I'm really not sure how to undo correctly here without saving a copy of any imported image while it's on the undo stack.
Can anyone give any recommendations about how best to implement undo/redo on a mobile device where memory and processor speed are low? I like the simplicity of 1 and 3 but it seems like the only realistic option is 2. I'm not sure how to cope with my second pathological example with this option though.
On the iPhone, Core Data has built in support for undo and redo. Just make your data model reflect the objects drawn and you can easily roll it back and forward between saves. Usually you would save the procedures and objects used to create the graphic instead of the graphic itself.
Edit:
OK, but this is just a little API
support for implementing number 2 and
won't help with the examples I gave.
The key idea to making this work is that you don't configure your data model to modal and persist the graphical output of the program, you configure it to modal and persist the process of creating the graphical output.
The naive way of creating a graphical program would be to set up the data flow like:
Input_UI-->Display_UI-->Data_Model
The user manipulates the Input_UI which directly alters the onscreen graphics of the Display_UI. Only when the user saved would the Data_Model come into play. This type of data flow makes undo/redo (and other things) very hard to implement especially in a painting e.g. compositing program. Every single operation has to know how to undo itself and has to be able operate on the altered graphic.
The better way is to set up a data flow like this:
Input_UI-->Data_Model-->Display_UI
The user manipulates the Input_UI which communicates to the Data_Model which manipulations the user chose. The Data_Model records the process e.g. "add file jpg.1 at rect {0,0,100,100}". A change to the Data_Model sends a notification to the Display_UI which reads the changed data and implements the process described.
The Data_Model rolls itself back and the Display_UI simply draws what the Data_Model tells it to. The Display_UI doesn't have to understand the undo process at all.
In a drawing program you would create logical layers of individual graphical objects so that redoing is just a matter of removing layers in the reverse order they were added. For painting/composition programs, you have to start at the last save point and recreate the graphic going forward until the last-1 step.
So, in your examples for a compositing program:
The Data_Model stores the coordinates of the selected area (the entire canvas) which is still just "rect {0,0,canvas.width,canvas.height}" and then the operation "fill with black". For undo, the Display_UI whips the image back to the last save point and then invisibly applies the changes made up to last-1.
You just need to save a cache of the image up until the next save. At that point, the Data_Modal commits all the changes and exports the composition to a file. The next time the app starts, it begins with the image from the last time. If you want infinite undo, then yes you have to save the imported image permanently.
The way to approach this is to ignore the GUI and instead think about how you would design an app to be run from the command line with out any GUI input or output. The Data_Modal would work just the same. It would save the text commands and the data (e.g. imported images) for creating the output image, not just a snapshot of the image on screen.
I like the simplicity of 1 and 3 but
it seems like the only realistic
option is 2.
I'm not sure what "3" is, since you only appear to have two options in your question.
With respect to the memory consumption of #1, it's only an issue if you use memory. Only hold onto history in memory for as long as it takes an AsyncTask (or possibly a regular background thread working off a LinkedBlockingQueue) to write them to the SD card. No SD card -- no undo/redo. On an undo, if your history has already written it to disk, reload it from disk. Just be sure to clean up the SD card (delete history on a clean exit, delete all lingering files on next startup).
Bear in mind that I have never written a painting application, let alone on Android, and so there may yet be performance problems (e.g., undo may take a second to load the bitmap off of the SD card).