I’m getting this log error in the editor since updating to Unity 2021.1.13f, previously I was on version 2020.3.7f
Log:
A Native Collection has not been disposed, resulting in a memory leak. Enable Full StackTraces to get more details.
Searching the forums and google I can only find information on this issue relating to dots and entities but I am not using dots or entities. I tried turning on stack trace logging in player settings but it doesn’t reveal anything useful.
Probably has something to do with an internal Unity package that you have installed. Unity is using Burst more and more under the hood. How many custom packages do you have installed?
ProGrids may use it, especially since it is experimental, or the other packages installed.
You may just need to download the Burst package and Jobs package (get both so you can turn on memory tracking) enabled it and see what is causing the issue. My bet is one of your custom packages.
Running into the same issue here, Unity 2021.2.18f1. I’ve tried adding the disposeUpload/disposeDownload handler bools before my SendWebRequest and everything is wrapped in a Using block so I just can’t figure out why its still leaking. Any thoughts? I’ve got all 3 disposes peppered throughout and it still leaks.
public IEnumerator RemoveServerInternal()
{
WWWForm serverData = new WWWForm();
print("Network List Communication Manager: Removing Server Entry");
// Assign all the fields required.
serverData.AddField("serverKey", AuthKey);
serverData.AddField("serverUuid", InstanceServerId);
using (UnityEngine.Networking.UnityWebRequest www = UnityEngine.Networking.UnityWebRequest.Post(Server + "/remove", serverData))
{
www.disposeUploadHandlerOnDispose = true;
www.disposeDownloadHandlerOnDispose = true;
yield return www.SendWebRequest();
if (www.responseCode == 200)
{
print("Successfully deregistered server with the NetworkListServer instance!");
www.Dispose();
www.uploadHandler.Dispose();
www.downloadHandler.Dispose();
}
else
{
Debug.LogError($"Failed to deregister the server with the NetworkListServer instance: {www.error}");
www.Dispose();
www.uploadHandler.Dispose();
www.downloadHandler.Dispose();
}
www.Dispose();
www.uploadHandler.Dispose();
www.downloadHandler.Dispose();
}
yield break;
}
Interesting, did not know that. Right now I’m seeing the leak when I stop the editor and I call the remove function above, I wonder if things are closing before the dipose is happening.
There are some very weird things that can happen with dispose. Like if you set a struct to another struct, dispose the first struct and then try and dispose the second struct. You will get an error since the first struct had its is created set to false but the copied struct did not. You really have to be aware of passing structs around.
A Native Collection has not been disposed, resulting in a memory leak. Allocated from:
Unity.Collections.NativeArray`1:.ctor(Byte[], Allocator) (at /Users/bokken/buildslave/unity/build/Runtime/Export/NativeArray/NativeArray.cs:69)
UnityEngine.Networking.UploadHandlerRaw:.ctor(Byte[]) (at /Users/bokken/buildslave/unity/build/Modules/UnityWebRequest/Public/UploadHandler/UploadHandler.bindings.cs:95)
UnityEngine.Networking.UnityWebRequest:SetupPost(UnityWebRequest, String) (at /Users/bokken/buildslave/unity/build/Modules/UnityWebRequest/Public/WebRequestExtensions.cs:176)
UnityEngine.Networking.UnityWebRequest:Post(String, String) (at /Users/bokken/buildslave/unity/build/Modules/UnityWebRequest/Public/WebRequestExtensions.cs:157)
Same problem here, tried many suggestions like use Dispose on UnityWebRequest object and it’s handlers, wrap into using statement, clear every object using in procedure, but the error keeps appearing
Unity version: 2021.2.9f1 personal.
line 346 in BaseServerConnect: using (UnityWebRequest request = UnityWebRequest.Post(uri, “POST”))
(it is in the end of another procedure outside using)
line 318: callOnComplete?.Invoke(result);
A Native Collection has not been disposed, resulting in a memory leak. Allocated from:
Unity.Collections.NativeArray1:.ctor(Byte[ ], Allocator) UnityEngine.Networking.UploadHandlerRaw:.ctor(Byte[ ]) UnityEngine.Networking.UnityWebRequest:SetupPost(UnityWebRequest, String) UnityEngine.Networking.UnityWebRequest:Post(Uri, String) <PostDataToServer>d__181:MoveNext() (at Assets\Scripts\BaseServerConnect.cs:346)
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
UnityEngine.MonoBehaviour:StartCoroutineManaged2(MonoBehaviour, IEnumerator)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
Battle:LaunchGetStageInfo(Int32, MonoBehaviour) (at Assets\Scripts\FromAE\Battle\Battle.cs:374)
BattleScript:StartStageControl() (at Assets\Scenes\Battle\BattleScript.cs:217)
BattleScript:StartAfterBattleLoaded() (at Assets\Scenes\Battle\BattleScript.cs:61)
BattleScript:BattleListLoadedHandler(Object, List`1) (at Assets\Scenes\Battle\BattleScript.cs:111)
Battle:OngoingBattlesLoadedHandler(String) (at Assets\Scripts\FromAE\Battle\Battle.cs:197)
d__17:MoveNext() (at Assets\Scripts\BaseServerConnect.cs:318)
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
Same problem here. It’s super frustrating. I am using a using statement and Disposing the request and using:
request.disposeUploadHandlerOnDispose = true;
request.disposeDownloadHandlerOnDispose = true;
as well. We should probably report a bug for this?
I have the same issue in Unity 2021.3.5. I keep getting this error a few seconds after sending a POST or PUT request. Disposing the UnityWebRequest does not work.
command?
If yes, then keep in mind, that they also create an UploadHandler within the “Post” command, so you Must not create your own UploadHandler!
I would recommend, using the “new UnityWebRequest(uri,data)” constructor instead like in the posts above.
I created the following abstract class here for all Post / Get requests. All you have to do is derive from it and you can use its Get / Post commands in all your API:
namespace Mavon.ServerCommunication
{
public abstract class BackendBaseUnityWebRequest
{
#if UNITY_EDITOR
public const string BackendURL = "http://127.0.0.1:2000"; // REPLACE THIS WITH YOUR LOCAL SERVER URL
#else
public const string BackendURL = "https://MyAPI.com; // REPLACE THIS WITH YOUR SERVER URL
#endif
public IEnumerator GetRequest<T> ( string requestURL, Action<string> error, Action<T> success)
{
using UnityWebRequest webRequest = UnityWebRequest.Get(BackendURL + requestURL);
webRequest.SetRequestHeader("withCredentials", "true");
yield return webRequest.SendWebRequest();
HandleRequestResult(webRequest, error, success);
}
public IEnumerator PostRequest<T>(string postData, string requestURL, Action<string> error, Action<T> success)
{
using UnityWebRequest webRequest = new (BackendURL + requestURL);
webRequest.method = UnityWebRequest.kHttpVerbPOST;
using UploadHandlerRaw uploadHandler = new(Encoding.ASCII.GetBytes(postData));
webRequest.uploadHandler = uploadHandler;
webRequest.downloadHandler = new DownloadHandlerBuffer();
webRequest.disposeUploadHandlerOnDispose = true;
webRequest.disposeDownloadHandlerOnDispose = true;
webRequest.SetRequestHeader("Content-Type", "application/json");
webRequest.SetRequestHeader("withCredentials", "true");
yield return webRequest.SendWebRequest();
HandleRequestResult(webRequest, error, success);
}
private void HandleRequestResult<T>(UnityWebRequest webRequest, Action<string> error, Action<T> success)
{
try
{
if (webRequest.result != UnityWebRequest.Result.Success)
{
error?.Invoke(webRequest.responseCode + " " + webRequest.error);
}
else
{
T response = JsonUtility.FromJson<T>(webRequest.downloadHandler.text);
success?.Invoke(response);
}
} catch(Exception ex)
{
Debug.LogError(ex.Message);
}
}
}
}
Hi Cobatheon,
I have tried many ways to break it, but it just does not break for me. Could you please run this coroutine here and see if that works for you?
public IEnumerator UnityWebRequestTestSimplePasses()
{
using UnityWebRequest webRequest = new("http://www.google.com", UnityWebRequest.kHttpVerbGET);
webRequest.downloadHandler = new DownloadHandlerBuffer();
webRequest.disposeUploadHandlerOnDispose = true;
webRequest.disposeDownloadHandlerOnDispose = true;
yield return webRequest.SendWebRequest();
Debug.Log(webRequest.downloadHandler.text);
}
For everyone else, if you struggle with UnityWebRequests, then there is a way more easy solution for you:
this way you can work with promises instead of coroutines which makes everything just a lot more easy. Everyone who works professionally with unity should use that package as it saves time and frustration ^^