Hoping someone can help me solve this.
Im making a very simple game on android 4.2.2 using just UI elements, ie no 3D, opengl, Just as a challenge really but I've ran into a little head ache.
I was having O.O.M issues with loading graphics (to be expected with android) so i looked for other routes and found bitmap factory and decided to use a simple implementation. with my images i was hitting up to 40mb allocated memory during game play so I reduced the files from 1080x1920x4bit to 540x960x4bit in a hope to reduce memory load but now it reaches up to 72mb during game play.
Am i missing something or is me thinking, halve the size of images and halve the memory usage? or does upscaling use that much more?
is there any way I can reduce this amount of memory down to a decent 16-20mb range?
Notes on the APP.
all images are stored in res/no-dp or res/xxdpi. And are all jpegs.
I have six pop up images which are 100x100dp jpegs and 5 x Life segments which are 50x50dp
this is the code im using to load the images from bitmap factory
Bitmap bMap = BitmapFactory.decodeResource(getResources(), R.drawable.dummy1nn);
button7.setImageBitmap(bMap);
and im loading the other images as background resources for now via buttons or image views.
I also have soundpool running on elements and a timer.
Any help would be appreciated. I dont want to post all my code as it is a right mess at the minute as im trying many different methods to get this working smoothly. The only issue i have is the memory load.
My current memory after running the game and letting it sit for 5 minutes is:-
Heap size - 73.086mb
allocated - 70.40mb
free - 2.625mb
used - 96.41%
objects - 47,161
I'm using LG Nexus 5 'hammerhead' as DEV device with unlocked bootloader and stock rom.
Thanks guys. :)
edit:
Answer was to use picasso, although there are a few image libraries out there i liked the simplicity of picasso a lot. and always use MAT when using images to make the relevant changes to quality/size and format to get the lowest memory print (mine dropped to 26mb peak)
have fun
Picasso is a really good library that will handle memory management, asynchronous loading, and caching for you.
Using your example, it would be used simply like this:
Picasso.with(this).load(R.drawable.dummy1nn).fit().into(button7);
Related
I'm building an application with very big sized images.
Almost all of my UI components are made of ImageViews.
I only have to show 12 images(ui components) on my first activity, but it consumes 80mb on startup.
The images are divided into each drawable directories using Android Drawable Importer.
By doing this I was able to reduce the runtime memory(which I can see on the Android studio's device monitor) to half, but it is still consuming 80~120mb of memories, which I believe is too much.
The first question is, isn't 80~120mb too much for a four screen(two activities, three fragments) application?
The second is, if it's too much then, what and how can I do to reduce memory usage?
When working with images keep in mind that there is a HUGE difference between compressed format (jpg, png..) and Bitmap. Computing the size of a Bitmap is pretty easy, it's width * height * 4 bytes (assuming that the bitmap has the default configuration argb888). So a full hd image that compressed is xy kb, when decompressed will occupy 8294400 bytes (~8mb). So my advice to reduce memory consumption is... scale down your images. You're asking if 80-120 mb is too much, well it seems like a lot but it really depends on what you're doing. What happen if you force garbage collection (there should be an icon in the device monitor)?Another thing to take into account is how to decompress the images, refer to this and use a library (Picasso, Glide..).
My application uses far too much memory, and uses a lot of images on one of the activities. I went to my main menu which only has 2 image buttons and a background image and removed all of the images from it to see what kind of memory it used... It still seems pretty high for nothing on the page.
http://imgur.com/6pfNlxf
Any idea what I'm doing wrong? Or are these normal numbers? In the activity that uses a lot of images, the allocated memory is much higher around 250MB, and crashes if I don't use my tiny scaled down images.
I m new to android programming and I am currently stuck on a big problem : Memory management.
Basically, my apps is trying to load 10 pictures (represented as byte[]) into 10 imageViews. The big problem is that (I think) decoding (via BitmapFactory.decodeByteArray()) and having 10 bitmap at once is extremely memory consuming so I get a memory error (OutOfMemoryError).
My question is more technical then trying to fix my code as I want to understand how it works and fix it after understanding what's wrong.
How can you get a Bitmap to take a small amount of space on RAM at runtime?
I m only loading 10 pictures but if I had to load 50 in a scroll view (not efficient I know, gridview is better but just for the purpose of the example) would it be possible ?
I have read the android documentation but it doesn't tell me how to take less space :/ I went through all the article of this section and loaded my bitmaps properly using the code given (load a scaled down version of my image through : https://developer.android.com/training/displaying-bitmaps/load-bitmap.html)
Right now, every Bitmap I load takes 20MB at runtime (way to much when limit is at around 130MB) and can I bring this down to less then 1MB by any technique?
I am Working with one android tablet application in which lots of work with Images.
i have to load hundred of large bitmap images in scroll view. one image is around 1Mb to 3 Mb.
i have already scale images using bitmap factory and sample size, and also load all the images in Async task.
i am loading all the images from SD card.
Still facing OUT OF MEMORY issue after scrolling some images.
any help would be appreciated.
thanks in advance.
hi hope your solution.
you can user Univarsal Image Loader. This is better api for image download and store in catch. and get from catch. it's a great api for image operation.
this case is often come while we getting bitmap so just use lazy loading. just take a look on this example
http://sunil-android.blogspot.in/2013/09/lazy-loading-image-download-from.html
To prevent your application from soaking up CPU time without getting anything done, the JVM throws this Error so that you have a chance of diagnosing the problem.
Its because of large bitmap memory in stored in native area
so it better i suggest you use libraries like Universal Image Loader or
Bitmap Fun from android
You have to find out when the OOM error occurs. Is it when you have too much bitmap cache in memory without releasing or you just meet it when you're decoding certain bitmap?
For the first situation, I think you should manage your bitmap cache yourself or using some effective 3rd-party library which mentions above.
For the second situation, I've met it on some low-performance mobile(usually with 512MB or less memory), when you decode a bitmap to requested size, it may needs a rather large memory to store the bitmap, for 240dpi devices, it's about 800 * 480 * 4 = 1.5MB, however you may fail to allocate that much memory on some machines cause they may have strict memory manage strategy to prevent that much memory allocation. You should just catch the OOM error and continue rather than get a crush.
Loading a bitmap in 1280x800 display will take 1280x800x4 byte (~4MB) memory. Java heap size is limited (~50MB) so you can not use lots of large bitmaps in your app. Using cache and reusing bitmap objects are necessary while working with bitmaps but another useful trick is to use larger hip size! to do so, add android:largeHeap="true" to Application tag in your manifest. It increases hip size to 4 or 5 times larger (~250MB) than normal. I hope this help other people reaching this thread while they search!
In: Decoding bitmaps in Android with the right size - it is posted that sampling down a bitmap may still lead to memory errors.
Is this issue still valid for newer versions of Android?
Does this mean that before sampling down, Android needs to load the full-size bitmap into memory? I believe this uses native memory, since image handling is implemented in native code.
Here is how you can get the available memory amount:
Runtime.getRuntime().maxMemory()
and here is an interesting blog about memory:
http://codelog.dexetra.com/getting-around-android-memory-blues
The problem with Android is ou never know when you may run ou of memory and the app just crashes. That is why you should try to avoid loading too large bimaps (I usually use maximum of 800 /600 or something like that depending on the screen orientation....)
If loading several bitmaps like for gallery or other view group you should use weak reference:
http://developer.android.com/reference/java/lang/ref/WeakReference.html
Also if you look at the example in the link you provided the scaling first decodes only bounds and then decides on the scale to use.
When you don't need a bitmap anymore call:
bitmap.recycle();
Newer versions might have more physical memory but it's still limited to whatever is the system stack size; that way, programming bitmap still should be done very carefully with the amount of memory used.
On this years Google I/O (2012) there was a great presentation named "Doing more with less" that shows some very nice caching techniques you should look into. I'm sure you can find this video on YouTube Android Developers account.
Found the video: http://www.youtube.com/watch?v=gbQb1PVjfqM