2048x2048的cc.SpriteFrame会额外占一些内存怎么回事

  • Creator 版本: 2.4.11

  • 目标平台:微信小游戏

  • 重现方式:
    1 打包后用iPhoneX扫开发版二维码预览
    2 点“加载bundle”按钮,比如现在初始内存占用是 404M
    3 点“png2048s Texs”按钮,加载10张2048x2048的纹理,内存增加了161M达到了565M(平均一张纹理占大约16M)
    3 点“png2048s SFs”按钮,加载对应的SpriteFrame,内存增加了53M达到了618M(这是为啥?)
    4 点“png2047s Texs”按钮,加载10张2047x2047的纹理,内存增加了161M达到了779M
    5 点“png2047s SFs”按钮,加载对应的SpriteFrame,内存并没有增加

TestMemory.zip (676.0 KB)

主要代码:
`const w = 40;
const d = 24;

@cc._decorator.ccclass
export default class Main extends cc.Component {

private bundle: cc.AssetManager.Bundle;
private spNamess: { [key: string]: Array<string> };
private container: cc.Node;

protected start(): void {

    console.log(cc.macro.CLEANUP_IMAGE_CACHE);
    cc.macro.CLEANUP_IMAGE_CACHE = true;

    this.container = this.node.getChildByName("container");

    const _btns = this.node.getChildByName("btns");
    _btns.getChildByName("加载bundle").on(cc.Node.EventType.TOUCH_START, () => {
        wx.loadSubpackage({
            name: "res", success: (res: { errMsg: string }) => {//{"errMsg":"loadSubpackage:ok"}
                console.log("loadSubpackage(" + "res" + ") success " + JSON.stringify(res));
                cc.assetManager.loadBundle("res", (err, bundle) => {
                    this.bundle = bundle;
                    this.spNamess = {};
                    for (const path in this.bundle._config.paths._map) {
                        const matchArr = path.match(/^Texture\/([^\/]+)\/([^\/]+)$/);
                        const spsName = matchArr[1];
                        let spNames: Array<string> = this.spNamess[spsName];
                        spNames || (this.spNamess[spsName] = spNames = []);
                        spNames.push(matchArr[2]);
                    }
                    console.log(this.spNamess);
                });
            }, fail: res => {
                console.error("loadSubpackage(" + "res" + ") fail" + JSON.stringify(res));
            }
        });
    });
    _btns.getChildByName("triggerGC").on(cc.Node.EventType.TOUCH_START, () => {
        wx?.triggerGC?.();
    });

    const _jpg2048s = _btns.getChildByName("jpg2048s");
    _jpg2048s.getChildByName("Texs").on(cc.Node.EventType.TOUCH_START, () => {
        this.loadTexs("2048x2048jpg");
    });
    _jpg2048s.getChildByName("SFs").on(cc.Node.EventType.TOUCH_START, () => {
        this.loadSFs("2048x2048jpg");
    });

    const _png2048s = _btns.getChildByName("png2048s");
    _png2048s.getChildByName("Texs").on(cc.Node.EventType.TOUCH_START, () => {
        this.loadTexs("2048x2048png");
    });
    _png2048s.getChildByName("SFs").on(cc.Node.EventType.TOUCH_START, () => {
        this.loadSFs("2048x2048png");
    });

    const _png2047s = _btns.getChildByName("png2047s");
    _png2047s.getChildByName("Texs").on(cc.Node.EventType.TOUCH_START, () => {
        this.loadTexs("2047x2047png");
    });
    _png2047s.getChildByName("SFs").on(cc.Node.EventType.TOUCH_START, () => {
        this.loadSFs("2047x2047png");
    });

    const _jpg1422s = _btns.getChildByName("jpg1422s");
    _jpg1422s.getChildByName("Texs").on(cc.Node.EventType.TOUCH_START, () => {
        this.loadTexs("1422x640jpg");
    });
    _jpg1422s.getChildByName("SFs").on(cc.Node.EventType.TOUCH_START, () => {
        this.loadSFs("1422x640jpg");
    });

    const _png1422s = _btns.getChildByName("png1422s");
    _png1422s.getChildByName("Texs").on(cc.Node.EventType.TOUCH_START, () => {
        this.loadTexs("1422x640png");
    });
    _png1422s.getChildByName("SFs").on(cc.Node.EventType.TOUCH_START, () => {
        this.loadSFs("1422x640png");
    });
}

private loadTexs(spsName: string): void {
    this.bundle.loadDir("Texture/" + spsName + "/", cc.Texture2D, (err, texs) => {
        console.log("loadTexs", spsName, texs.length);
    });
}
private loadSFs(spsName: string): void {
    this.bundle.loadDir("Texture/" + spsName + "/", cc.SpriteFrame, (err, sfs) => {
        console.log("loadSFs", spsName, sfs.length);
        const i = this.container.children.length;
        let x: number = i % w;
        let y: number = (i - x) / w;
        x--;
        for (const sf of sfs) {
            if (++x >= w) {
                x = 0;
                y++;
            }
            const node = new cc.Node();
            const sp = node.addComponent(cc.Sprite);
            sp.spriteFrame = sf;
            this.container.addChild(node);
            node.width = node.height = 22;
            node.x = x * d;
            node.y = -y * d;
        }
    });
}

}
`

顶 期待大牛 深入讲解~

期待~~~~~

应该是生成了Mipmaps的原因,只有2的n次幂的图片才会生成。用1024的图片同样会产生一些额外的内存。但是实际这些纹理并没有开启gen mipmaps,在chorme中测试是正常的。但是在微信小游戏中就会产生。
测试引擎:2.4.7 && 2.4.11
新工程增加了1024的图片TestMemorynew.zip (325.1 KB)