-
Notifications
You must be signed in to change notification settings - Fork 8
Open
Description
アプリ画面の内容を動画として保存する際に使用させて頂いています。 RealtimeInstantReplaySession を使用して画面やRenderTextureの内容を繰り返し動画として出力すると、アプリのメモリ使用量がどんどん上がっていく現象に遭遇しています。
環境は windows11 25H2、
scripting backend は mono、
Unityのバージョンは 6000.0.65f1 です。
使用バージョンはおそらく d194c16 です。
(おそらく、というのは2/25の夕方にmainのzipをDLしたものを使ったため明確なバージョンが特定できてないです。)
検証用プロジェクトの画面収録
5分かけて30秒の動画を繰り返し出力していますがメモリ使用量が増加していく様子を記録しました。
InstantReplayProj.2026-02-26.13-14-07.webm
特に8本目の動画を保存した後、次の収録開始時にメモリ使用量が顕著に跳ね上がります (4:10 あたり)
検証に使ったソースコード
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using InstantReplay;
using Unity.Profiling;
using UnityEngine;
using UnityEngine.UI;
public class SampleScene : MonoBehaviour
{
[SerializeField] private Text _timeText;
[SerializeField] private float _recordSeconds = 30f;
[SerializeField] private float _waitSeconds = 1f;
[SerializeField] private string _outputDirectoryName = "InstantReplayVideos";
private int _recCounter;
private string _status = "Idle";
private string _lastOutputPath = "-";
private CancellationTokenSource _loopCancellation;
private ProfilerRecorder _systemUsedMemoryRecorder;
private void OnEnable()
{
_systemUsedMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "System Used Memory");
_loopCancellation = new CancellationTokenSource();
_ = RecordLoopAsync(_loopCancellation.Token);
}
private void OnDisable()
{
if (_loopCancellation != null)
{
_loopCancellation.Cancel();
_loopCancellation.Dispose();
_loopCancellation = null;
}
if (_systemUsedMemoryRecorder.Valid)
_systemUsedMemoryRecorder.Dispose();
}
private void Update()
{
if (_timeText == null)
return;
var systemUsedMemoryMb = GetSystemUsedMemoryMb();
_timeText.text =
$"{DateTimeOffset.Now:HH:mm:ss}\ncount={_recCounter} status={_status}\nlast={_lastOutputPath}\nmem={systemUsedMemoryMb:0.0}MB";
}
private async Task RecordLoopAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
RealtimeInstantReplaySession session = null;
try
{
_status = "Recording";
session = RealtimeInstantReplaySession.CreateDefault();
await Task.Delay(TimeSpan.FromSeconds(_recordSeconds), cancellationToken);
_status = "Exporting";
var outputPath = BuildOutputPath(_recCounter + 1);
var savedPath = await session.StopAndExportAsync(_recordSeconds, outputPath);
_recCounter++;
_lastOutputPath = Path.GetFileName(savedPath);
_status = "Saved";
Debug.Log($"InstantReplay saved: {savedPath}");
}
catch (OperationCanceledException)
{
break;
}
catch (Exception ex)
{
_status = "Error";
Debug.LogException(ex);
}
finally
{
session?.Dispose();
}
// cleanup
Resources.UnloadUnusedAssets();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
try
{
_status = "Waiting";
await Task.Delay(TimeSpan.FromSeconds(_waitSeconds), cancellationToken);
}
catch (OperationCanceledException)
{
break;
}
}
_status = "Stopped";
}
private string BuildOutputPath(int sequence)
{
var directory = Path.Combine(Application.persistentDataPath, _outputDirectoryName);
Directory.CreateDirectory(directory);
var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
return Path.Combine(directory, $"InstantReplay_{timestamp}_{sequence:D4}.mp4");
}
private double GetSystemUsedMemoryMb()
{
if (!_systemUsedMemoryRecorder.Valid || _systemUsedMemoryRecorder.Count == 0)
return 0d;
return _systemUsedMemoryRecorder.LastValue / (1024d * 1024d);
}
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels