creador-Recursos de detección de fugas


título: creador-recursos para la detección de fugas
categorías: Cocos2dx
etiquetas: [creador, optimización, fuga, memoria]
fecha: 2023-03-29 14:48:48
comentarios: falso
mathjax: verdadero
toc: verdadero

creador-Recursos de detección de fugas


precuela

  • Lanzamiento de recursos: https://docs.cocos.com/creator/manual/zh/asset/release-manager.html

  • Antes de ejecutar pruebas relevantes y tomar instantáneas, asegúrese de ejecutar gc js varias veces

    imagen-20230329152312826


Código para información de volcado relevante

  • vertedero

    public dumpPath(path: string) {
          
          
        let bundleName = "resources"
    
        let bundle = assetManager.getBundle(bundleName);
        let asset01 = bundle.get(path);
        let uuid = asset01._uuid
    
        this.dumpUuidRecur(uuid)
    }
    
    private dumpUuidRecur(uuid: string, depth: number = 1) {
          
          
        let pre = "---".repeat(depth)
        var asset01 = assetManager.assets.get(uuid)!;
    
        var uuids: string[] = assetManager.dependUtil.getDepsRecursively(uuid)!;
        LogUtil.D(`${
            
            pre} dumpUuidRecur: ${
            
            uuid}, refCnt: ${
            
            asset01.refCount}\nasset:`, asset01, "\nuuid:", uuids)
    
        uuids.forEach(uuid => {
          
          
            this.dumpUuidRecur(uuid, ++depth)
        });
    }
    
    public dump() {
          
          
        assetManager.assets.forEach((value: Asset, key: string) => {
          
          
            console.log(assetManager.assets.get(key));
        })
        console.log(`当前资源总数:${
            
            assetManager.assets.count}`);
    }
    
    
    
    

Carga estática: varios prefabricados se refieren a la misma imagen

  1. Hice dos de los prefabricados más simples, que se refieren a la misma imagen.

    imagen-20230329145021401

  2. Ejecutar carga dinámica

  3. Echa un vistazo a la información de recursos de estos dos caminos prefabricados

    imagen-20230329145353550

    • Se encontró que spriteFrame mantiene recuentos de referencias, texture2d e imageAsset no mantienen recuentos de referencias

      Según la documentación de Guanfan: https://docs.cocos.com/creator/manual/zh/asset/release-manager.html#%E8%B5%84%E6%BA%90%E7%9A%84%E9% 9D%99%E6%80%81%E5%BC%95%E7%94%A8

      Solo necesitamos mantener el recuento de referencias prefabricadas -1, el motor mantendrá la tecnología de referencia spriteFrame y luego mantendrá texture2d e imageAsset, spriteFrame es equivalente al Material en la imagen de la derecha

      imagen-20230329145540060


Recuento de referencia -1 cuando se destruye la casa prefabricada

  1. En el caso de que no se cargue ningún prefabricado, la cantidad total es 55

    imagen-20230329145900957

  2. Cuando se cargan prefabricados, la cantidad total es 60

    imagen-20230329145917606

  3. Destruya el prefabricado, y el recuento de referencia del prefabricado es -1, y el número total vuelve a 55.
    El recurso es normal

    imagen-20230329145937661


Carga dinámica: correcta

  1. En el caso de que no se cargue ningún prefabricado, la cantidad total es 55

    imagen-20230329150045997

  2. Después de cargar el prefabricado, cargue dinámicamente una imagen de big002 y el recuento de referencia +1, total 63

    imagen-20230329150122949

  3. Destruya el prefabricado, y el recuento de referencia del prefabricado es -1, y el recuento de referencia de recursos de los recursos cargados dinámicamente es -1, y el número total vuelve a 55.
    El recurso es normal

    ¡¡¡La clave aquí es mantener el recuento de referencia de los recursos cargados dinámicamente por ti mismo!!!

    imagen-20230329150147216


Carga dinámica: error

  1. En el caso de que no se cargue ningún prefabricado, la cantidad total es 55

    imagen-20230329150301368

  2. Después de cargar el prefabricado, cargue dinámicamente una imagen de big002 (no opere el conteo de referencia), el número total es 63

    imagen-20230329150322070

  3. Destruir el prefabricado, la cantidad total no ha vuelto a 55
    recursos no es normal

    imagen-20230329150345262

    Al ver que, aunque el recuento de referencias de big002 spriteFrame es 0, ¿por qué no se ha publicado todavía? Como resultado, el texture2d asociado y el imageAsset no se han publicado

    El activador de cocos se activa mediante el método de disminución del recuento de referencia por decRef, todo lo cual aún debe llamarse manualmente para liberar

    • 3.7.1 Código fuente relacionado

      imagen-20230329150427482


El seguimiento de recursos mantiene automáticamente los recuentos de referencia

Después de conocer las reglas de publicación, puede agregar un rastreador al administrador de recursos personalizado, para que los recursos cargados mantengan automáticamente los recursos cargados relevantes de acuerdo con el final del ciclo de vida del nodo, para que los desarrolladores no tengan que preocuparse. sobre problemas de conteo de referencias, solo se preocupan por la generación y destrucción de nodos

  1. De hecho, el principio es muy simple, que consiste en colgar un componente en el nodo para registrar los recursos durante la carga, a fin de mantener el recuento de referencia.

    • AssetTracker.ts

      import {
              
               _decorator, Component, Node, Asset, SpriteFrame } from 'cc';
      import {
              
               LogUtil } from '../log/LogUtil';
      const {
              
               ccclass, property } = _decorator;
      
      @ccclass('AssetTracker')
      export class AssetTracker extends Component {
              
              
      
          public static trace(go: Node, ast: Asset) {
              
              
              let at = go.getComponent(AssetTracker)
              if (!at) {
              
              
                  at = go.addComponent(AssetTracker)
              }
              at.traceInner(ast)
          }
      
          private _astArr = new Array<Asset>()
      
          traceInner(ast: Asset) {
              
              
              ast.addRef()
              this._astArr.push(ast)
          }
      
          onDestroy() {
              
              
              // LogUtil.D(`--- onDestroy, cnt: ${this._astArr.length}, _astArr:\n`, this._astArr)
              this._astArr.forEach((ast, idx, arr) => {
              
              
                  ast.decRef()
              })
              this._astArr = null
          }
      
          debugDump() {
              
              
              this._astArr.forEach((ast, idx, arr) => {
              
              
                  LogUtil.D("", ast)
              })
          }
      }
      
  2. Ejemplo de interfaz de carga relacionada

    // ------------------------------------ 对外接口 begin
    public async instantiateAsync(prefabPath: string, parent?: Node) {
          
          
        return new Promise<Node>((resolve) => {
          
          
            this.load(prefabPath, (err: Error, asset: Prefab) => {
          
          
                if (err) {
          
          
                    LogUtil.E(`--- instantiateAsync error, path: ${
            
            prefabPath}, err:`, err)
                    resolve(null)
                    return
                }
    
                let go = instantiate(asset);
                AssetTracker.trace(go, asset) // 资源计数追踪
                if (parent)
                    go.parent = parent
                resolve(go)
            })
        })
    }
    
    // refGo 挂点, 最好是资源要依附的节点
    public async loadAssetAsync<T extends Asset>(assetPath: string, refGo: Node) {
          
          
        return new Promise<T>((resolve) => {
          
          
            this.load(assetPath, (err: Error, asset: T) => {
          
          
                if (err) {
          
          
                    LogUtil.E(`--- loadAssetAsync error, path: ${
            
            assetPath}, err:`, err)
                    resolve(null)
                    return
                }
    
                AssetTracker.trace(refGo, asset) // 资源计数追踪
                resolve(asset)
            })
        })
    }
    
    // refGo 挂点, 最好是资源要依附的节点
    public async loadRemoteAsync<T extends Asset>(url: string, opts: IRemoteOptions, refGo: Node) {
          
          
        return new Promise<T>((resolve) => {
          
          
            this.loadRemote(url, opts, (err: Error, asset: T) => {
          
          
                if (err) {
          
          
                    LogUtil.E(`--- loadRemoteAsync error, url: ${
            
            url}, err:`, err)
                    resolve(null)
                    return
                }
    
                AssetTracker.trace(refGo, asset) // 资源计数追踪
                resolve(asset)
            })
        })
    }
    // ------------------------------------ 对外接口 end
    

Medido

  1. Cuando el prefabricado no está cargado, el número total es 55, y la memoria y el caché de imágenes son los siguientes

    imagen-20230329152013866

  2. En el caso de cargar imágenes prefabricadas y dinámicamente, el número total es 61, y la memoria y el caché de imágenes son los siguientes

    imagen-20230329152036689

  3. Destruya los nodos prefabricados, el número total vuelve a 55, y la memoria y el caché de imágenes también vuelven al valor inicial, lo que indica que los recursos se liberan normalmente.

    imagen-20230329152054504


Supongo que te gusta

Origin blog.csdn.net/yangxuan0261/article/details/129838344
Recomendado
Clasificación