Closed khanzzirfan closed 9 years ago
Just to let you know that I have added these following URLs to test the image loading and the app fails after 40 images loaded. Could be these images are big in size? but I thought the disk cache should handle it when it reaches the size limit.
"http://photojournal.jpl.nasa.gov/jpeg/PIA10001.jpg", "http://photojournal.jpl.nasa.gov/jpeg/PIA10002.jpg", "http://photojournal.jpl.nasa.gov/jpeg/PIA10003.jpg", "http://photojournal.jpl.nasa.gov/jpeg/PIA10004.jpg", "http://photojournal.jpl.nasa.gov/jpeg/PIA10005.jpg", "http://photojournal.jpl.nasa.gov/jpeg/PIA10006.jpg", "http://photojournal.jpl.nasa.gov/jpeg/PIA10007.jpg", "http://photojournal.jpl.nasa.gov/jpeg/PIA10008.jpg", "http://photojournal.jpl.nasa.gov/jpeg/PIA10009.jpg", "http://photojournal.jpl.nasa.gov/jpeg/PIA10010.jpg", "http://photojournal.jpl.nasa.gov/jpeg/PIA10011.jpg", "http://photojournal.jpl.nasa.gov/jpeg/PIA10012.jpg", "http://photojournal.jpl.nasa.gov/jpeg/PIA10013.jpg", "http://photojournal.jpl.nasa.gov/jpeg/PIA10014.jpg",
"http://photojournal.jpl.nasa.gov/jpeg/PIA10015.jpg",
"http://photojournal.jpl.nasa.gov/jpeg/PIA10016.jpg",
"http://photojournal.jpl.nasa.gov/jpeg/PIA10017.jpg",
"http://photojournal.jpl.nasa.gov/jpeg/PIA10018.jpg",
"http://photojournal.jpl.nasa.gov/jpeg/PIA10019.jpg",
"http://photojournal.jpl.nasa.gov/jpeg/PIA10020.jpg",
"http://photojournal.jpl.nasa.gov/jpeg/PIA10021.jpg",
Hi @sahilkhan99 I tried with 40 images like in your example and don't have any issue. Could you write your device name and Android version? Also are you experiencing this in simulator or in real device?
Hi @molinch I"m testing on samsung galaxy s3 with the sample app, app can be found here https://github.com/sahilkhan99/learnings
Scroll through all the way to the end,and come back, it will crash..when it exceeds 64 MB of memory.
The below is the OOM message.
[dalvikvm-heap] Clamp target GC heap from 70.062MB to 64.000MB
[dalvikvm-heap] Forcing collection of SoftReferences for 786448-byte allocation
[dalvikvm-heap] Clamp target GC heap from 70.062MB to 64.000MB
[dalvikvm-heap] Out of memory on a 786448-byte allocation.
[skia] --- decoder->decode returned false
Something wrong happened while asynchronously loading/decoding image: https://farm6.staticflickr.com/5753/19900030444_7672fb9fb4_b.jpg
Java.Lang.OutOfMemoryError: Exception of type 'Java.Lang.OutOfMemoryError' was thrown.
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in
With Genymotion that simulates a Galaxy S3/Android 4.1.1 I don't reproduce this issue. Do you have more feedback to share?
The genymotion emulator gives the devices too much memory. The OS is probably limiting you. FWIW, I've also seen an occasional OOM crash on our app as well on real devices. If you try it in a regular Android AVD emulator, the OOM crashes happen more often. Seems like there's a leak in FFImageLoading or it's not loading images efficiently (in native Android, you can load a reduced size image into memory instead of the whole thing by setting bitmap samplesize on the decoder....not sure if you can do this in C# as well but it would help)... When this happens, I also see cache corruption which is a bigger issue. When FFImage is told to load an image, it sometimes loads the wrong one :-(
@kenkyee DownSample() method is here to load images efficiently. When you use it, only the reduced size is loaded into memory. Regarding the OOM I will investigate, since there are 2 garbage collectors involved most of the time OOMs come from code using FindViewById and not disposing the views. Meanwhile you can also update your android manifest to use android:largeHeap="true"
I already have largeheap enabled (it was crashing a lot w/o it) and am using DownSample everywhere. To reproduce the OOM memory swap, try having a collapsing toolbar header w/ an image and then a recyclerview that you can scroll through at high speed. I'm doing CancelLoading on the ImageViewAsync in the viewholder before telling FFImage to load into it, so it should not be leaking.
Could you elaborate on the FindViewById and not disposing the view? E.g., an example of what not to do and a best practice?
A couple of commits have been done to improve the situation:
@kenkyee @sahilkhan99 Could you try to reproduce your issues using git sourcecode?
@kenkyee Regarding FindViewById: you should dispose all views that you get with FindViewById. Otherwise this leads to leaks in the app.
@molinch I'm Testing the sample app with in this library, and I have scroll forward to 80 images and when I started scolling back, GC keep increasing and the OOM happens again.
I'm using my phone Samsung galaxy S3 for testing. Here is the application console output.
On positive note, app won't crash because of OOM and OOM message can only be seen while debugging in the application console output window. As I believe the whole code is written under try catch blocks and as soon as OOM exceeds, it is calling GC and restting the disk cache. Hence app continues to load images with out crash.
[Mono] GC_BRIDGE waiting for bridge processing to finish
[Mono] GC_OLD_BRIDGE num-objects 560 num_hash_entries 609 sccs size 609 init 0.00ms df1 1.65ms sort 0.22ms dfs2 1.29ms setup-cb 0.58ms free-data 0.48ms links 68/68/77/2 dfs passes 1237/677
[Mono] GC_MAJOR: (LOS overflow) pause 17.28ms, total 17.58ms, bridge 54.63ms major 1248K/1232K los 10122K/25446K
[dalvikvm-heap] Grow heap (frag case) to 28.007MB for 4096016-byte allocation
[dalvikvm-heap] Grow heap (frag case) to 44.012MB for 16384016-byte allocation
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/6410112_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/5913500_l.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/5141027_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/8823717_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/Calendar_Icon.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/5078256_xxl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/5288016_xxl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/7815172_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
[Mono] GC_OLD_BRIDGE num-objects 546 num_hash_entries 591 sccs size 591 init 0.00ms df1 2.22ms sort 0.30ms dfs2 2.24ms setup-cb 0.54ms free-data 0.52ms links 65/65/74/2 dfs passes 1202/656
[Mono] GC_MAJOR: (LOS overflow) pause 27.02ms, total 27.39ms, bridge 64.69ms major 1264K/1248K los 9885K/26608K
[dalvikvm-heap] Grow heap (frag case) to 28.742MB for 4096016-byte allocation
[dalvikvm-heap] Grow heap (frag case) to 45.127MB for 16384016-byte allocation
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/7322971_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/7776812_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/7293022_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/7630040_xxl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/9109180_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/7772004_l.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/13710590_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/4_ZHVibHlhMTAuanBn.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/6516975_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
[Mono] GC_OLD_BRIDGE num-objects 550 num_hash_entries 599 sccs size 599 init 0.00ms df1 2.66ms sort 0.67ms dfs2 3.36ms setup-cb 0.81ms free-data 0.99ms links 70/70/78/2 dfs passes 1219/669
[Mono] GC_MAJOR: (LOS overflow) pause 39.02ms, total 39.78ms, bridge 70.24ms major 1296K/1264K los 9731K/26424K
[dalvikvm-heap] Grow heap (frag case) to 29.701MB for 4096016-byte allocation
[dalvikvm-heap] Grow heap (frag case) to 45.326MB for 16384016-byte allocation
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/15180498_xxl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/4174831_l.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/11653740_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/299011_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/2562812_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/6286346_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/13097271_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/6670302_xxl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/4864431_xxl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/8094101_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
[Mono] GC_BRIDGE waiting for bridge processing to finish
[Mono] GC_OLD_BRIDGE num-objects 573 num_hash_entries 623 sccs size 623 init 0.00ms df1 2.92ms sort 0.42ms dfs2 1.87ms setup-cb 0.87ms free-data 0.79ms links 71/71/80/2 dfs passes 1267/694
[Mono] GC_MAJOR: (LOS overflow) pause 28.37ms, total 28.71ms, bridge 47.93ms major 1344K/1296K los 9424K/26481K
[dalvikvm-heap] Grow heap (frag case) to 29.599MB for 4096016-byte allocation
[dalvikvm-heap] Grow heap (frag case) to 44.733MB for 16384016-byte allocation
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/5324611_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/glasses_icons_gray.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/6851391_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Image from cache: http://files.usvit.alejtech.eu/peto/6670302_xxl.jpg;CropCircleTransformation();GrayscaleTransformation()
Image from cache: http://files.usvit.alejtech.eu/peto/13097271_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Image from cache: http://files.usvit.alejtech.eu/peto/6286346_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Image from cache: http://files.usvit.alejtech.eu/peto/2562812_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Image from cache: http://files.usvit.alejtech.eu/peto/299011_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Image from cache: http://files.usvit.alejtech.eu/peto/11653740_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Image from cache: http://files.usvit.alejtech.eu/peto/4174831_l.jpg;CropCircleTransformation();GrayscaleTransformation()
Image from cache: http://files.usvit.alejtech.eu/peto/15180498_xxl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/6516975_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/4_ZHVibHlhMTAuanBn.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/13710590_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/7772004_l.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/9109180_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/7630040_xxl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/7293022_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/7776812_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/7322971_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/7815172_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/5288016_xxl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/5078256_xxl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/Calendar_Icon.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/8823717_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
[dalvikvm-heap] Grow heap (frag case) to 58.331MB for 1364240-byte allocation
[dalvikvm-heap] Grow heap (frag case) to 58.658MB for 1364240-byte allocation
[dalvikvm-heap] Clamp target GC heap from 64.658MB to 64.000MB
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/5141027_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/5913500_l.jpg;CropCircleTransformation();GrayscaleTransformation()
[dalvikvm-heap] Grow heap (frag case) to 59.675MB for 705616-byte allocation
Generating/retrieving image: http://files.usvit.alejtech.eu/peto/6410112_xl.jpg;CropCircleTransformation();GrayscaleTransformation()
[dalvikvm-heap] Forcing collection of SoftReferences for 1232116-byte allocation
[dalvikvm-heap] Clamp target GC heap from 64.105MB to 64.000MB
[dalvikvm-heap] Out of memory on a 1232116-byte allocation.
Can't apply transformation CropCircleTransformation() to image http://files.usvit.alejtech.eu/peto/6410112_xl.jpg
Java.Lang.OutOfMemoryError: Exception of type 'Java.Lang.OutOfMemoryError' was thrown.
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in
Dum question, but how do I get the code into our project...it's currently using the NuGet. And when should the FIndViewById references be Disposed? It's generally a coding pattern in Android to use viewholders and do all the FindViewById when an Activity is created. They're released automatically when those objects are destroyed.
For memory usage, I see similar issues as sahilkhan99 in our app. We have the typical Android app w/ a collapsing hero image at the top and a few listviews in viewpagers w/ images. If I flip through really fast and swipe around the viewpager, the new image gets corrupted (with a random image from one of the listviews you're swiping) which is bizarre because it stays in place and has already been loaded. I'm starting to look at it through Xamarin Studio's Profiler and memory usage does keep growing but it doesn't say where it's from...just lots of byte[] allocations and a call to java inputstream. Will update if I find anything useful or chase this down...
@sahilkhan99 Yes basically the app isn't crashing anymore due to OOMs. I will contact our Xamarin support to know why the GC is not collecting without an explicit call to it (when we get an OOM). Since the crash is fixed, even though the underlying issue remains, it's less "sensible".
@kenkyee I will update Nuget packages today. Objects found via FindViewById should be disposed in OnDestroy via calling .Dispose() on each, as well as having event handlers removed via -= MyEventHandler. Regarding the image corruption to be honest I have no idea since i don't have this issue on my side. If you have any sample to share I'm happy to look at it.
Spent some time w/ the Xamarin Profiler...doesn't give much useful info because it doesn't show you much about what objects are using memory on the Android side. I can take a memory snapshot, then switch viewpagers, fling around the recyclerview lists and take another snapshot and only a few MB are used. But the total app mem usage has ballooned to 300MB.
But FWIW, I swapped in the Square.Picasso NuGet and I don't get that header image corruption any more and it feels a bit faster. Still dies eventually though because the OOM happens on the Android side instead of the Xamarin side :-P In a Recyclerview's viewholder, you can't dispose imageviews....they're managed by the recyclerview/viewholder. If you dispose them, you'd have to look them up each time and this would make the viewholder speedup negligible.
@sahilkhan99 @kenkyee The changes are now on NuGet sorry for the delay.
Btw @kenkyee even though OOMs still occur, crashes are fixed, since the GC runs when it happens. Regarding the speed I don't know: where do you believe is the speed latency? while retrieving images from internet? While displaying them? While loading them from disk cache or from disk? I am still interested to look at your image corruption issue but maybe you can raise another ticket for that. It could be nice if you attached to it a sample or at least a screencast.
Sorry..."speedier" should be lagginess...sometimes when ffimage was used, the UI would pause a little (probably doing GC is my guess). FFImage actually displayed images faster in the recyclerview of images like it was using more threads than Picasso. I'm still puzzled by that Xamarin Profiler screencap above. I'd bet if you tried it w/ your sample app, you'd see similar oddness. I get the sense it's some Xamarin issue w/ it holding onto imageviews too long in recyclerviews or something weird like that. The memory usage shouldn't be spiking so hard on the Android side when there is no similar spike on the Xamarin side. And out of curiosity, what problems did you have w/ Picasso so I can keep an eye out for them?
FFImageLoading 1.1.6 has been released: https://github.com/molinch/FFImageLoading/releases/tag/v1.1.6
This release improves a lot the situation so I will consider this issue as done. If you still experience weird behaviours, lags, or OOMs I would suggest creating a new issue & referencing #30. Here it's getting too long & we mix a couple of things.
Regarding your questions:
@kenkyee @sahilkhan99 Bitmap cache/bitmap pool has been heavily rewritten, based on TangoAndCache. This change drastically limits allocations. Could you give it a try?
Hi, The sample app give me an OOM error after loading 40 images. Can the Disk cache can be cleared when loading after 35 images or based on size of the image cache?
Thank you.