En este momento estás viendo Fuga de memoria debido a MapBox en Unity

 – Unity

Fuga de memoria debido a MapBox en Unity – Unity

Fuga de memoria debido a MapBox en Unity

– UnityAssets3Free

hola , soy Juan y para hoy os traigo
esta nueva pregunta

Uso MapBox SDK en mi proyecto de Unity y solo muestro el mapa. No uso otros servicios como direcciones ni nada por el estilo. De alguna manera siempre recibo un error de que hay una pérdida de memoria. Como mi proyecto es un iOS y Android aplicación una pérdida de memoria no suena tan bien para mí jaja.

El error con las referencias es este:

A Native Collection has not been disposed, resulting in a memory leak. Allocated from:
Unity.Collections.NativeArray`1:.ctor(Byte[], Allocator)
UnityEngine.Networking.UploadHandlerRaw:.ctor(Byte[])
Mapbox.Unity.Telemetry.<PostWWW>d__8:MoveNext() (at AssetsMapboxUnityTelemetryTelemetryEditor.cs:82)
Mapbox.Unity.Utilities.Routine:MoveNext() (at AssetsMapboxUnityUtilitiesRunnable.cs:130)
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
UnityEngine.MonoBehaviour:StartCoroutineManaged2(IEnumerator)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
Mapbox.Unity.Utilities.Routine:.ctor(IEnumerator) (at AssetsMapboxUnityUtilitiesRunnable.cs:116)
Mapbox.Unity.Utilities.Runnable:Run(IEnumerator) (at AssetsMapboxUnityUtilitiesRunnable.cs:47)
Mapbox.Unity.Telemetry.TelemetryEditor:SendTurnstile() (at AssetsMapboxUnityTelemetryTelemetryEditor.cs:37)
Mapbox.Unity.MapboxAccess:ConfigureTelemetry() (at AssetsMapboxUnityMapboxAccess.cs:196)
Mapbox.Unity.MapboxAccess:SetConfiguration(MapboxConfiguration, Boolean) (at AssetsMapboxUnityMapboxAccess.cs:108)
Mapbox.Unity.MapboxAccess:LoadAccessToken() (at AssetsMapboxUnityMapboxAccess.cs:161)
Mapbox.Unity.MapboxAccess:.ctor() (at AssetsMapboxUnityMapboxAccess.cs:66)
Mapbox.Unity.MapboxAccess:get_Instance() (at AssetsMapboxUnityMapboxAccess.cs:41)
Mapbox.Unity.Map.<SetupAccess>d__88:MoveNext() (at AssetsMapboxUnityMapAbstractMap.cs:609)
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
UnityEngine.MonoBehaviour:StartCoroutineManaged(String, Object)
UnityEngine.MonoBehaviour:StartCoroutine(String, Object)
UnityEngine.MonoBehaviour:StartCoroutine(String)
Mapbox.Unity.Map.AbstractMap:MapOnStartRoutine(Boolean) (at AssetsMapboxUnityMapAbstractMap.cs:534)
Mapbox.Unity.Map.AbstractMap:Start() (at AssetsMapboxUnityMapAbstractMap.cs:500)

Apunta a los scripts de MapBox que vienen con el SDK. No sé si debería incluirlos aquí ya que no los he tocado en absoluto y son muy genéricos y apuntan a muchos otros scripts.

¿Alguien tiene alguna idea? ¿O puedo simplemente ignorar esto y mi aplicación funcionará bien? Hasta ahora no tengo problemas de prueba por lo que puedo decir.

¡Gracias por pensar conmigo!

2 respuestas 2

El siguiente error solo se producirá en el editor y no afectará a las plataformas de segmentación porque hay UNITY_EDITOR macro presente en su Assets/Mapbox/Unity/Telemetry/TelemetryEditor.cs mapa vial.

Si aún desea corregir este error, debe llamar a Dispose una vez que haya terminado de usar un objeto UnityWebRequest, independientemente de si la solicitud tuvo éxito o no, simplemente reemplace el Publicar WWW método con lo siguiente:

        IEnumerator PostWWW(string url, string bodyJsonString)
        {
            byte[] bodyRaw = Encoding.UTF8.GetBytes(bodyJsonString);

#if UNITY_2017_1_OR_NEWER
            using (UnityWebRequest postRequest = new UnityWebRequest(url, "POST"))
            
                postRequest.SetRequestHeader("Content-Type", "application/json");

                postRequest.downloadHandler = new DownloadHandlerBuffer();
                postRequest.uploadHandler = new UploadHandlerRaw(bodyRaw);

                yield return postRequest.SendWebRequest();

                while (!postRequest.isDone)  yield return null; 

                if (!postRequest.isNetworkError)
                
#else
                var headers = new Dictionary<string, string>();
                headers.Add("Content-Type", "application/json");
                headers.Add("user-agent", GetUserAgent());
                var www = new WWW(url, bodyRaw, headers);
                yield return www;

                while (!www.isDone)  yield return null; 

                // www doesn't expose HTTP status code, relay on 'error' property
                if (!string.IsNullOrEmpty(www.error))
                
#endif
                    PlayerPrefs.SetString(Constants.Path.TELEMETRY_TURNSTILE_LAST_TICKS_EDITOR_KEY, "0");
                
                else
                
                    PlayerPrefs.SetString(Constants.Path.TELEMETRY_TURNSTILE_LAST_TICKS_EDITOR_KEY, DateTime.Now.Ticks.ToString());
                
            
        

El texto indica que Mapbox.Unity.Map.AbstractMap usa algunos recursos no administrados. Esto es omnipresente en cualquier clase que trate con imágenes o dibujos. Yo personalmente no conozco esta clase, pero con ese nombre no me sorprende en absoluto.

El GC no limpia automáticamente los recursos no administrados de manera oportuna. Si bien, por lo general, hay un finalizador para limpiar esta función con el tiempo, generalmente no hay opción para esperar. Y en este caso, parece que incluso hay una excepción para asegurarse de que no se olvide: ¡increíblemente conveniente!

Es su trabajo asegurarse de que los recursos no administrados se limpien antes de descartar la última referencia llamando Mapbox.Unity.Map.AbstractMap.Dispose().

Mi consejo general cada vez que se trata de algo descartable es: «Crear. Usar. Desechar. Todo en la misma pieza de código, e idealmente usando el usando declaración.» En general, es recomendable rediseñar su código para que pueda seguir este patrón siempre que sea remotamente posible.

Hay una excepción muy rara. En ese raro caso, debe implementar el patrón de descarte.

El patrón Dispose tiene dos casos de uso:

  • Usted maneja los recursos no administrados directamente. Esto básicamente nunca sucede. Todos los casos probables ya están cubiertos por bibliotecas de clases. En ese caso, primero escribe un Finalizer y luego agrega una función Dispose para mayor comodidad.
  • Tiene un campo de cualquier tipo que implementa IDisposeable. En ese caso, su propia clase debe implementar IDisposeable. El único propósito es transmitir la llamada Dispose() para cualquier campo desechable que contenga su tipo. Este es el caso de uso del 99%.

Como el código es prácticamente idéntico, el finalizador suele formar parte de la función Dispose(bool). Las únicas diferencias entre fianlizer y Dispose son:

  • Las llamadas del finalizador nunca se retransmiten a los campos Desechables. El Finalizador es un asunto entre cada Instancia y el GC.
  • Una llamada Dispose siempre se retransmite para los campos Disposeable. Este relé es, literalmente, la única razón por la que implementa IDisposeable en primer lugar.

nota: si aun no se resuelve tu pregunta por favor dejar un comentario y pronto lo podremos de nuevo , muchas gracias

por hoy,hasta la proxima

Deja una respuesta