App crashes when loading hundreds of high res images in scrollview

Good day currently my app crashes on an ios device whenever i try to load hundreds of items at the same time with for loop. Apparently this happens because of memory load, it makes my ios device crash because of overloading, meanwhile here in simulator it doesn’t crashes.

Currently my workaround is first I load 20 items 1st, then when everytime the bottom has been reached, I load 10 more, until it reaches its limit.

but with my style, there is a certain point where the app crashes. are there any good ideas on how to load multiple images all at the same time.

here is my code:

local displayImages = function(lVal) if lVal \> 1 then else if #storeData \>= 20 then dulo = 20 else dulo = #storeData end end if dulo \<= 0 then else for i = lVal, dulo do d = d + 1 imagesText[i] = display.newImageRect( storeData[i].imageBig..".png", system.DocumentsDirectory, 744, 500) imagesText[i].x = X imagesText[i].y = Y imagesText[i].anchorX = 0 imagesText[i].anchorY = 0--Futura-Medium end

Note: there are also other objects that are loaded along with images I just posted the idea on how it will work.

thanks in advance

Your Mac’s memory management and your iPhone/iPad’s memory management are worlds apart.  On OS-X, you generally 4 to 32X the available RAM.  Many Mac’s have 4GB of RAM these days. Older Mac’s might have 2G worse case. My Mac has 16GB of memory.

The typical iDevice has between 0.25GB and 1GB of RAM.

Of that memory, on OS-X takes up a fraction of the memory and your apps have plenty of memory to use. Of course you can run multiple apps…  On top of that OS-X uses a paging system that will use your hard drive space to hold memory that’s not being used at the moment. 

Your iDevice does not use paging and you may have half of the RAM or less for your app.  You don’t say what “High Rez” is, but let’s say you’re dealing with the 8 megapixel images from an iPhone 5.  It uses a 3,264 x 2,448 image. This image takes up roughly 32MB of RAM. If your phone only has 256MB free (0.25GB) (which is being generous), you only have memory to load 8 of the images before you run out of memory.  Frequently you might only have 100mb or so free, which would be 4 photos total.

You simply are not going to be able to load hundreds of high-res images, if you’re talking camera size images.

Rob

Sure, I wrote up a sample showing how to have as many images as you want.  My sample dynamically unloads the images when they move off-screen while retaining the display object, and re-loads the image when it is about to be on-screen again:

Get the code here:

http://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2014/10/Texture%20Memory%20Management.zip

Watch the talk about it here:

https://coronalabs.com/blog/coronageek/corona-geek-111/

Although I wrote my own simple scrolling group, the same can be applied to the scrollView widget.

@roaminggamer thanks for this, what should I put in this parameters though? 

Correct me if I’m wrong, but what you’re doing in this project is, whenever the image is offscreen you change it to a fillW.png so it won’t really consume that much of a memory space? Right?

– onScreen.frameFiller = function( obj, fill, fill2, buffer, baseDirectory1, baseDirectory2 )

@roaminggamer this works yes, but performance wise my app started to struggle, yet it still loads all the image that I want.

It struggles because of all the Runtime that are running. that’s why this happens.

That’s not a final solution.  It is a framework to build a better solution upon.

You can do a lot to optimize it.  You can even abandon the enterFrame solutions (per object) and centralize the entire algorithm.

The core of it is the ‘on-screen check’ (which can also be optimized to simply checking y positions if its a vertical scroller.

I’ve used an optimized variant of this to build layers vertical scrollers containing multiple horizontal scrollers, and then containing thousands of images (equivalent to hundreds of megabytes if all shown at once) and only had performance hits on low end devices.

As I said, the code I provided is just a starting point.  

Regardless, If this doesn’t work for you, you’ll still need to break the problem down into:

  • removing images completely when they are not needed.                                   OR
  • removing the texture associated with the image when it is not needed.

Okay thanks for the advice. One last thing, does this work if the image is out of bounds to the left or to the right

I want to say yes, but its better to double check.  I’d just but a print statement in the hiding code, then move an image off screen left or right to find out.

Your Mac’s memory management and your iPhone/iPad’s memory management are worlds apart.  On OS-X, you generally 4 to 32X the available RAM.  Many Mac’s have 4GB of RAM these days. Older Mac’s might have 2G worse case. My Mac has 16GB of memory.

The typical iDevice has between 0.25GB and 1GB of RAM.

Of that memory, on OS-X takes up a fraction of the memory and your apps have plenty of memory to use. Of course you can run multiple apps…  On top of that OS-X uses a paging system that will use your hard drive space to hold memory that’s not being used at the moment. 

Your iDevice does not use paging and you may have half of the RAM or less for your app.  You don’t say what “High Rez” is, but let’s say you’re dealing with the 8 megapixel images from an iPhone 5.  It uses a 3,264 x 2,448 image. This image takes up roughly 32MB of RAM. If your phone only has 256MB free (0.25GB) (which is being generous), you only have memory to load 8 of the images before you run out of memory.  Frequently you might only have 100mb or so free, which would be 4 photos total.

You simply are not going to be able to load hundreds of high-res images, if you’re talking camera size images.

Rob

Sure, I wrote up a sample showing how to have as many images as you want.  My sample dynamically unloads the images when they move off-screen while retaining the display object, and re-loads the image when it is about to be on-screen again:

Get the code here:

http://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2014/10/Texture%20Memory%20Management.zip

Watch the talk about it here:

https://coronalabs.com/blog/coronageek/corona-geek-111/

Although I wrote my own simple scrolling group, the same can be applied to the scrollView widget.

@roaminggamer thanks for this, what should I put in this parameters though? 

Correct me if I’m wrong, but what you’re doing in this project is, whenever the image is offscreen you change it to a fillW.png so it won’t really consume that much of a memory space? Right?

– onScreen.frameFiller = function( obj, fill, fill2, buffer, baseDirectory1, baseDirectory2 )

@roaminggamer this works yes, but performance wise my app started to struggle, yet it still loads all the image that I want.

It struggles because of all the Runtime that are running. that’s why this happens.

That’s not a final solution.  It is a framework to build a better solution upon.

You can do a lot to optimize it.  You can even abandon the enterFrame solutions (per object) and centralize the entire algorithm.

The core of it is the ‘on-screen check’ (which can also be optimized to simply checking y positions if its a vertical scroller.

I’ve used an optimized variant of this to build layers vertical scrollers containing multiple horizontal scrollers, and then containing thousands of images (equivalent to hundreds of megabytes if all shown at once) and only had performance hits on low end devices.

As I said, the code I provided is just a starting point.  

Regardless, If this doesn’t work for you, you’ll still need to break the problem down into:

  • removing images completely when they are not needed.                                   OR
  • removing the texture associated with the image when it is not needed.

Okay thanks for the advice. One last thing, does this work if the image is out of bounds to the left or to the right

I want to say yes, but its better to double check.  I’d just but a print statement in the hiding code, then move an image off screen left or right to find out.