Giter Site home page Giter Site logo

Comments (10)

pandamicro avatar pandamicro commented on May 16, 2024

Which version of creator are you using?

from cocos-engine.

DrMoriarty avatar DrMoriarty commented on May 16, 2024

Cocos Creator v1.3.3 for MacOSX

from cocos-engine.

pandamicro avatar pandamicro commented on May 16, 2024

@DrMoriarty Sorry there is indeed some issues with v1.3.3 native loader. The solution is:

  1. Please try v1.4
  2. Try not to release any resources in v1.3.3, then it won't reload again, so memory won't grow up dramatically

With v1.4, you can release resources with cc.loader.release, here is couple of examples described in the API:

// Release a texture which is no longer need
cc.loader.release(texture);
// Release all dependencies of a loaded prefab
var deps = cc.loader.getDependsRecursively('prefabs/sample');
cc.loader.release(deps);
// If there is no instance of this prefab in the scene, the prefab and its dependencies like textures, sprite frames, etc, will be freed up.
// If you have some other nodes share a texture in this prefab, you can skip it in two ways:
// 1. Forbid auto release a texture before release
cc.loader.setAutoRelease(texture2d, false);
// 2. Remove it from the dependencies array
var deps = cc.loader.getDependsRecursively('prefabs/sample');
var index = deps.indexOf(texture2d._uuid);
if (index !== -1)
    deps.splice(index, 1);
cc.loader.release(deps);

B.t.w, we still have some minor memory leak issue in v1.4, and we are investigating into it.

from cocos-engine.

pandamicro avatar pandamicro commented on May 16, 2024

Another thing need to mention is that JSB memory deallocation is always delayed, because JS object can only be freed when the garbage collection(GC) is invoked, the timing of GC is controlled by Spidermonkey. You can also manually call GC with

cc.sys.garbageCollect();

Some objects may need various times of GC to be finally released

from cocos-engine.

DrMoriarty avatar DrMoriarty commented on May 16, 2024

@pandamicro
I've downloaded CocosCreator_v1.4.0_2017021001.dmg and modified my test project. Now I loaded and unloaded the big texture in the same scene:

cc.Class {
    extends: cc.Component

    properties: {
        loaded: 
            default: false
            visible: false
        texture: 
            default: null
            visible: false
    }

    checkResources: (event) ->
        if @loaded
            @unloadResources()
        else
            @loadResources()

    loadResources: () ->
        url = cc.url.raw 'resources/splash_4.png'
        cc.log 'Load', url
        cc.loader.load url, ((err, res) ->
            @texture = res
            @loaded = true
        ).bind(@)

    unloadResources: () ->
        cc.log 'Unload texture'
        cc.loader.release(@texture._id)
        @loaded = false
        cc.sys.garbageCollect();
}

When I tested the application on iOS device or simulator I have this memory usage graph:
2017-02-22 13 23 15

The first button click loads the texture (and allocates the memory) and next button clicks produces no equal memory release.

I also checked the first test case and it behaviour was exactly the same. Without autoReleaseAssets = true all scenes was loaded in memory once and never released. With autoReleaseAssets = true all scenes loads it's resources every time when I switched the scene.

from cocos-engine.

DrMoriarty avatar DrMoriarty commented on May 16, 2024

@pandamicro also I noticed that during the second test Ref::release() was never called for cocos2d::Texture2D object.

Ref::retain() for Texture2D was called twice: from TextureCache::addImageAsyncCallBack function and from jsb_ref_get_or_create_jsobject function.

from cocos-engine.

DrMoriarty avatar DrMoriarty commented on May 16, 2024

@pandamicro Finally I noticed that I have no ideas what is the right way to release a texture. None of these are helped: cc.loader.release(@texture), cc.loader.release(@texture._id), cc.loader.release(@texture._uuid), cc.loader.releaseRes(@texture.url, cc.Texture2D), cc.loader.releaseRes(cc.url.raw('resources/splash_4.png'), cc.Texture2D)

Some of them does nothing, another part raises an error. What is the right way to release a texture (which is loaded by cc.loader.load(url)) ?

from cocos-engine.

DrMoriarty avatar DrMoriarty commented on May 16, 2024

@pandamicro
May be I was inattentive when tested first time cocos creator 1.4. Now I checked the first test case with additional cc.sys.garbageCollect(); when scene is released. And it works pretty well!
2017-02-22 15 29 28

The worked code is:

cc.Class {
    extends: cc.Component

    properties: {
    }

    bntNext: (event, sceneName) ->
        cc.director._scene.autoReleaseAssets = true
        cc.director.loadScene sceneName, 
            () ->
                cc.log sceneName, 'loaded'
            () ->
                cc.log 'current scene unloaded'
                cc.sys.garbageCollect();
}

from cocos-engine.

pandamicro avatar pandamicro commented on May 16, 2024

The thing is that GC can only release objects that have no reference, in Web platform it's pretty straight forward and effective. But with JSB it's much complicated, in the new memory model introduced after v1.3, most C++ object life cycle was controlled by JS object, but we still have some C++ to JS references, for example, JSCallbackWrapper, JSFunctionWrapper, JSScheduleWrapper, they make GC more complicated. Sometimes you will need to invoke GC more than once to release all useless objects.

from cocos-engine.

pandamicro avatar pandamicro commented on May 16, 2024

Finally I noticed that I have no ideas what is the right way to release a texture. None of these are helped: cc.loader.release(@texture), cc.loader.release(@texture._id), cc.loader.release(@texture._uuid), cc.loader.releaseRes(@texture.url, cc.Texture2D), cc.loader.releaseRes(cc.url.raw('resources/splash_4.png'), cc.Texture2D)

Often you can't release the texture directly, even if you can remove it from the loader's cache, but there will always be a SpriteFrame hold its reference, then Texture2D's JS object is always alive.

For example, if you know your texture's sprite frame was only used by a Sprite, then remove the Sprite from the scene, or set its spriteFrame property to null. And release the SpriteFrame from the Loader recursively :

var spriteFrameToRelease = sprite.spriteFrame;
sprite.spriteFrame = null;
// Release all dependencies of a loaded sprite frame
var deps = cc.loader.getDependsRecursively(spriteFrameToRelease);
cc.loader.release(deps);

This way can effectively remove all reference of thie Texture2D, if the spriteFrameToRelease wasn't referenced anywhere else

from cocos-engine.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.