@fuzigiwa2 (義将 藤極)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Unityで非ファイルデータを含む映像ファイルを送信後にメモリが解放されない

Unityで開発しております。

サーバーに非ファイルデータを含む映像ファイルを送信しております。
送信終了後のメモリを確認すると

送信前:254MB
送信中:1990MB
送信後:1715MB

といった具合にメモリが解放されておりません。

public class AppWebRequest : Singleton<AppWebRequest>
{
    private string _urlMain     = "https://hoge.info/v1";
    private long _responseCode = 0;
    public MediaUploadGetData   _dataMediaUpload = null;

    public IEnumerator mediaUpload( MediaUploadApiData a_data )
    {
        string l_url = _urlMain + "/media";

        using (UnityWebRequest request = new UnityWebRequest( l_url, UnityWebRequest.kHttpVerbPOST))
        {
            byte[] l_file_data = File.ReadAllBytes( a_data._path );

            List<IMultipartFormSection> requestData = new List<IMultipartFormSection>();
            requestData.Add( new MultipartFormFileSection( "file", l_file_data, a_data._name, "video/*" ) );
            requestData.Add( new MultipartFormDataSection( "user_ids",  a_data.user_ids.ToString() ) );
            requestData.Add( new MultipartFormDataSection( "title",     System.Text.Encoding.UTF8.GetBytes( a_data.title ) ) );
            requestData.Add( new MultipartFormDataSection( "comment",   System.Text.Encoding.UTF8.GetBytes( a_data.comment ) ) );

            byte[] boundary = null;
            byte[] formSections = null;
            try {
                boundary = UnityWebRequest.GenerateBoundary();
                formSections = UnityWebRequest.SerializeFormSections( requestData, boundary );
            }catch ( Exception e ) {
                yield break;
            }
            request.timeout = 180;

            request.uploadHandler   = (UploadHandler) new UploadHandlerRaw( formSections );
            request.downloadHandler = (DownloadHandler) new DownloadHandlerBuffer();

            request.SetRequestHeader("X-Requested-With", "XMLHttpRequest" );
            request.SetRequestHeader("Content-Type", "multipart/form-data; boundary="+System.Text.Encoding.UTF8.GetString(boundary) );
            request.SetRequestHeader( "Authorization", "Bearer "+ _access_token );

            var async = request.SendWebRequest();
            while( true )
            {
                if (request.isHttpError || request.isNetworkError)
                {
                    _responseCode = request.responseCode;
                    break;
                }
                if( async.isDone )
                {

                    string l_file = request.downloadHandler.text;
                    try {
                        _dataMediaUpload = JsonUtility.FromJson<MediaUploadGetData>( l_file );
                    }catch ( Exception e ) {
                    }
                    _responseCode = request.responseCode;
                    break;
                }
                yield return null;
            }
        }
    }
}

通信処理はこのようになります。
通信終了後に「System.GC.Collect();」を読んでおりますがメモリは解放されませんでした。

こちら他にメモリ開放手段などありますでしょうか。
また、「UnityWebRequest.SerializeFormSections()」を行うとメモリが読み込みファイル以上に増えますが、
こちらはいったいなぜでしょうか。
ファイル読み込み時のバイト配列など、「requestData.Add」した後にnullを挿入しましたが、結果は変わりませんでした。

Unity 2020.3.1f1を使用しております。

よろしくお願い致します。

0 likes

2Answer

巨大なファイルをReadAllBytesで全てメモリに読み込もうとしてるのが実装としてあまり良くない気がします。
試しにHttpClientを使用してみてはどうでしょう?
Send large file via HttpClient

また、「UnityWebRequest.SerializeFormSections()」を行うとメモリが読み込みファイル以上に増えますが、こちらはいったいなぜでしょうか。

Webでバイナリ送信する際はBASE64に変換するので、その分サイズが増えているのではないでしょうか。

0Like

現状の追記なのですが、記入したコードでUnityエミュレーター上ではメモリが解放されていることを確認しております。
しかし、Windows向けアプリとして出力したもので確認すると開放されておりませんでした。
メモリは「GC.GetTotalMemory(false)」で取得した数値を画面上に表示することで確認しております。

0Like

Your answer might help someone💌