A downloadable book


1. Understanding Javascript Garbage Collection

You cannot manually do the garbage collection in javascript. To ensure that an object can be GC, all references to the object need to be deleted. The destroy() method provided by Laya.Sprite will help set the internal reference to null.

When the object is set to null, it will not be deleted from memory immediately. The garbage collector will only run when the system thinks the memory is low enough. Memory allocation (rather than object deletion) triggers garbage collection.

During garbage collection, it may take up a lot of CPU and affect performance. Reusing objects can help limit the chance of garbage collection. In addition, set the reference to null as much as possible so that the garbage collector takes less time to find the object. Sometimes (for example, two objects refer to each other), it is impossible to set two references to null at the same time. Then the garbage collector will have to scan for the object that cannot be accessed and clear them, which will consume more performance.

2. Object pooling

Object Pooling is a great way to optimize your projects and lower the burden that is placed on the CPU when having to rapidly create and destroy GameObjects. It is a good practice and design pattern to keep in mind to help relieve the processing power of the CPU to handle more important tasks and not become inundated by repetitive create and destroy calls. In this tutorial, you will learn to use Object Pooling to optimize your projects.

Using object pools can effectively reduce the overhead of object creation and avoid frequent garbage collection, thereby optimizing the fluency of the game.

Object pool optimization is a very common optimization method in game development.

A lot of objects such as bullets, NPC and special effects. in the game are constantly being created and removed which is very costly and may cause memory fragmentation.

In HTML5 games, the javascript garbage collection will use lots of CPU and is likely to cause a stuttering or laggy issue upon garbage collecting.

The object pool technology can solve this problem well. When the object A is removed from the game scene, it is recycled to the object pool, then when the same type of object is needed, A is directly taken out of the object pool for reuse.

The advantage is that it reduces the overhead when instantiating the object, and allows the object to be reused repeatedly, reducing the chance of new memory allocation and the garbage collector running.

When game starts, creates the entire collection of objects up front (usually in a single contiguous allocation) and initializes them all to the “not in use” state.

When you want a new object, ask the pool for one. It finds an available object, initializes it to “in use”, and returns it. When the object is no longer needed, it is set back to the “not in use” state. This way, objects can be freely created and destroyed without needing to allocate memory or other resources.

To the memory manager, we’re just allocating one big hunk of memory up front and not freeing it while the game is playing. In other words, the object pools grabs a big chunk of memory when the game starts, and don’t free it until the game ends. This way, the curse of memory fragmentation won't happen.

When to Use object pool

This pattern is used widely in games for obvious things like game entities and visual effects, but it is also used for less visible data structures such as currently playing sounds. Use Object Pool when:

  • You need to frequently create and destroy objects.
  • Objects are similar in size.
  • Allocating objects on the heap is slow or could lead to memory fragmentation.
  • Each object encapsulates a resource such as a database or network connection that is expensive to acquire and could be reused.

Be careful though

The pool may waste memory on unneeded objects.

The size of an object pool needs to be tuned for the game’s needs. When tuning, it’s usually obvious when the pool is too small (there’s nothing like a crash to get your attention). But also take care that the pool isn’t too big. A smaller pool frees up memory that could be used for other fun stuff.



3. Resource unload

Many resources will always be loaded when the game is running. These resources should be unloaded in time after use, otherwise they will remain in the memory. 

For example, when a game page is no longer needed, the resources of it can be released to avoid occupying memory. But if this page will be used later, also it takes a lot of CPU usage to init and render this page, probably just hide it or deactivate it. You need to trade off between the CPU and memory usage.


4. The loading of image or atlas 

After loading the image or atlas, the engine will start processing image resources. If an atlas is loaded, each sub-image is processed. If a large number of images are processed at one time, this process may cause prolonged freezes.

Only the resources needed in the current level or scene should be loaded. Do not load all at a time.

Also after the resource is used, it can also be unloaded to release the memory.


5. Optimize draw call and use dynamic frame rate settings


By default, our logical frame and rendering frame are the same frame rate, which is 60 frames by default.

But in the actual project development process, like some turn-based games, card games, or some games that do not need to be too real-time, there is actually no need for logic to keep the frame rate of 60 frames running, resulting in a waste of performance. , resulting in serious power consumption and fever of the mobile phone.


6. Reduce object property lookups

Any object in JavaScript is dynamic, you can add properties at will. However, looking up an attribute among a large number of attributes can be time consuming. If you need to use a specific property of an object frequently, you can use a local variable to save that property or its reference.


Leave a comment

Log in with itch.io to leave a comment.