RuntimeLogWatcher lags Editor and bloats RAM
tracked
kawashirov
For some reason, RuntimeLogWatcher from UdonSharp loads entire log files of VRChat in memory and scans it, every editor tick.
If for some reason, there is a large log file of VRChat (for example because some world spams with messages), then right after Unity starts, RuntimeLogWatcher can't handle it gracefully and just explodes in UI hangs and RAM usage. Before Unity loads in usable state, it is already have less than 1fps and uses dozens gigs of ram.
For some reason is also cannot be turned off: even if Output watch mode is set to Disabled, it is still there.
Log In
Skuld
Please consider the following code, which both AICom and VRCX do when parsing the log:
using (FileStream stream = new FileStream(logFile.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
string line;
int currentLine = 0;
for (currentLine = 0; (line = reader.ReadLine()) != null; currentLine++)
{
if (currentLine < lastLine)
continue;
ParseLineAsync(line);
}
lastLine = currentLine;
initSuppress = false;
}
The concept is fast scan to the current line, reading line by line, instead of reading the entire file into memory. Meanwhile remembering the last line you read, so you're not repeating operations against already processed lines.
Sure each line still has to be read 1 by 1, but this avoids all 3+GB (at times) of the file being loaded into memory. And the above code can be done within an async Task, with yields to help prevent locking up the UI while it reads.
I saw the SDK code is doing:
string fullFileContents = reader.ReadToEnd();
The editor will throw out of memory when the file is that big, and will lock up the editor each time it tries and fails to read. Which is directly in the OnEditorUpdate loop, which makes it more jarring.
This post was marked as
tracked
kawashirov
I read the code of RuntimeLogWatcher a lil bit, and it seems there is a cascade of issues:
- The code that search for player name is extremely heavy; it reads entire file. This can hang Editor.
- It is intended to find the name once and shouldn't run anymore. But if it can't find the name for some reason, it runs again and again each file update.
- If vrchat spams messages for some reason then file update events will be triggered every editor frame, so all that heavy logic fill run every editor frame. This will hang Editor at all into unusable state.
- RuntimeLogWatcher is always loaded with SDK
- It also operates when listenForVRCExceptions is on but idk what is that lol
kawashirov
Idk what is the best way to fix this, but I believe:
This should work off-thread as it doesn't rely on unity objects. As I know unity allows Debug.Log calls from other threads, so it should be ok to post messages from there. If some info from the scene is necessary, well, at least search/parsing of the string might be off-thread and then posted into main to further populating and analysis.
The file shouldn't read entirely. If we read some old lines and there wasn't a name, then it will not be there in future too.
The RuntimeLogWatcher shouldn't be loaded from the start. It is indented to read messages from launched testing worlds. But if vrc just run in background and not related to the project there is no need for watch. It might be auto loaded on build test, or manually through menu.
kawashirov
Obvious workaround: exit VRChat and delete the logs just works fine.
But still isn't very convenient to use.