17

I'm working on a HTML 5 game, it is already online, but it's currently small and everything is okay.

Thing is, as it grows, it's going to be loading many, many images, music, sound effects and more. After 15 minutes of playing the game, at least 100 different resources might have been loaded already. Since it's an HTML5 App, it never refreshes the page during the game, so they all stack in the background.

I've noticed that every resource I load - on WebKit at least, using the Web Inspector - remains there once I remove the <img>, the <link> to the CSS and else. I'm guessing it's still in memory, just not being used, right?

This would end up consuming a lot of RAM eventually, and lead to a downgrade in performance specially on iOS and Android mobiles (which I slightly notice already on the current version), whose resources are more limited than desktop computers.

My question is: Is it possible to fully unload a Resource, freeing space in the RAM, through JavaScript? Without having to refresh the whole page to "clean it".

Worst scenario: Would using frames help, by deleting a frame, to free those frames' resources?.

Thank you!

3
  • 3
    One thing you could try doing is setting the corresponding resource handle to null. As long as the resource is not referenced from anywhere any more, the memory it uses should be garbage-collected by the javascript engine Commented Sep 20, 2011 at 17:05
  • I'm going to try that! Thanks! Do you mind sharing with me a link with examples on how to access the Resources the browser has loaded? I'm having a hard time finding that on Google =/ Commented Sep 20, 2011 at 17:11
  • In Firefox and Chrome, the garbage collector seems to run when switching to another tab. I'm not sure how useful this is for you, but if the user is not continually playing, you should be fine trusting the garbage collector. Commented Sep 20, 2011 at 17:37

5 Answers 5

4

Your description implies you have fully removed all references to the resources. The behavior you are seeing, then, is simply the garbage collector not having been invoked to clean the space, which is common in javascript implementations until "necessary". Setting to null or calling delete will usually do no better.

As a common case, you can typically call CollectGarbage() during scene loads/unloads to force the collection process. This is typically the best solution when the data will be loaded for game "stages", as that is a time that is not time critical. You usually do not want the collector to invoke during gameplay unless it is not a very real-time game.

Frames are usually a difficult solution if you want to keep certain resources around for common game controls. You need to consider whether you are refreshing entire resources or just certain resources.

Sign up to request clarification or add additional context in comments.

4 Comments

Yes! That's why I wanted to avoid the use of Frames. I don't want duplicates of my resources, it has to be optimized. - So are you saying by Invoking that method, JS will clean from memory everything I'm not using at that exact moment? (like images that are loaded, but are not inserted in the HTML anywhere?)
@ArtPulse: It is supposed to force it's operation, though I've seen some older implementations interpret it as a hint. So all unreferenced objects would be removed. Usually it's best to start off just continuing to add resources and verify that the GC background operation is insufficient before considering using it, but game developers have been using it more frequently because they know places where a GC collect can happen without interfering with game play.
All righty! But, does it remove only unused JS variables? What if an image that was downloaded by an <img /> tag on the HTML, is no longer being used by any <img /> tag anymore, and therefore it's unused? Will GC remove that Resource?
@ArtPulse: The HTML data will be unloaded by the browser on the browser's discretion. Some browsers may have garbage collection, but that is becoming a worse choice in many Ajax-enabled designs. Typically, this has become seen as something that is handled on refresh of the page data, and should be treated like that by the programmer. If there are no more tags referencing, it should be thought of as clean. Unfortunately, I know of no browser-specific way to enforce that (and in most cases, no browser-specific way either).
3

All you can do is rely on JavaScript's built in garbage collection mechanism.

This kicks in whenever there is no reference to your image.

So assuming you have a reference pointer for each image, if you use:

img.destroy()

or

img.parentNode.removeChild(img)

Worth checking out: http://www.ibm.com/developerworks/web/library/wa-memleak/

Also: Need help using this function to destroy an item on canvas using javascript

EDIT

Here is some code that allows you to load an image into a var.

<script language = "JavaScript">


var heavyImage = new Image(); 
heavyImage.src = "heavyimagefile.jpg";

......

heavyImage = null; // removes reference and frees up memory

</script>

This is better that using JQuery .load() becuase it gives you more control over image references, and they will be removed from memory if the reference is gone (null)

Taken from: http://www.techrepublic.com/article/preloading-and-the-javascript-image-object/5214317

Hope it helps!

3 Comments

Each part is loaded through jQuery.load(), which inserts HTML with <img /> tags in it, among other stuff. That's how everything works, actually. By removing them, they are still visible at the Web Inspector. Do you mean I should load every image from JavaScript to be able to "unload" them from JavaScript as well?
That sounds great. Though, implementing everything on the game through this medium would take longer and change a lot of what has been done already. But will keep it in mind as a possibility, thanks =)
Don't forget you can use an Array() to hold multiple images (if that helps at all)
3

There are 2 better ways to load images besides a normal <img> tag, which Google brilliantly discusses here:

http://www.youtube.com/watch?v=7pCh62wr6m0&list=UU_x5XG1OV2P6uZZ5FSM9Ttw&index=74

  1. Loading the images in through an HTML5 <canvas> which is way way faster. I would really watch that video and implement these methods for more speed. I would imagine garbage collection with canvas would function better because it's breaking away from the DOM.

  2. Embedded data urls, where the src attribute of an image tag is the actual binary data of the image (yeah it's a giant string). It starts like this: src="data:image/jpeg;base64,/9j/MASSIVE-STRING ... " After using this, you would of course want to use a method to remove this node as discussed in the other answers. (I don't know how to generate this base64 string, try Google or the video)

2 Comments

Sounds good! Will definitely keep this in mind. Thanks Devin!
eh we all should volunteer our time to others on StackOverflow
1

You said Worst scenario: Would using frames help, by deleting a frame, to free those frames' resources

It is good to use frame. Yes, it can free up resource by deleting the frames.

3 Comments

It does work? Well at least that's a failsafe. I could load a whole Battle in a frame, for example, and once it's done, kill it. I'll try and see how it responds.
I would discourage the use of frames. They actually dropped the <frame> tag in HTML5 w3.org/TR/html5-diff
I dislike frames. That's why I don't want to use them xD
0

All right, so I've made my tests by loading 3 different HTML into an < article > tag. Each HTML had many, huge images. Somewhat about 15 huge images per "page".

So I used jQuery.load() function to insert each in the tag. Also had an extra HTML that only had an < h1 >, to see what happened when a page with no images was replacing the previous page.

Well, turns out the RAM goes bigger while you start scrolling, and shoots up when going through a particularly big image (big as in dimensions and size, not just size). But once you leave that behind and lighter images come to screen, the RAM consumption actually goes down. And whenever I replaced using JS the content of the page, the RAM consumption went really down when it was occupying to much. Virtual Memory remained always high and rarely went down.

So I guess the browser is quite smart about handling Resources. It does not seem to unload them if you leave it there for a long while, but as soon you start loading other pages or scrolling, it starts loading / freeing up.

I guess I don't have anything to worry about after all...

Thanks everyone! =)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.