<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: GameOptim</title>
    <description>The latest articles on DEV Community by GameOptim (@gameoptim).</description>
    <link>https://dev.to/gameoptim</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3712156%2F2856be03-78df-4cc3-848e-f48a8d1ce581.png</url>
      <title>DEV Community: GameOptim</title>
      <link>https://dev.to/gameoptim</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gameoptim"/>
    <language>en</language>
    <item>
      <title>How Do You Tell Whether a Unity Stutter Is From GPU Shader Cost, Bandwidth, or Thread Blocking?</title>
      <dc:creator>GameOptim</dc:creator>
      <pubDate>Fri, 06 Nov 2026 02:05:52 +0000</pubDate>
      <link>https://dev.to/gameoptim/how-do-you-tell-whether-a-unity-stutter-is-from-gpu-shader-cost-bandwidth-or-thread-blocking-503l</link>
      <guid>https://dev.to/gameoptim/how-do-you-tell-whether-a-unity-stutter-is-from-gpu-shader-cost-bandwidth-or-thread-blocking-503l</guid>
      <description>&lt;p&gt;&lt;strong&gt;Cycles/Pixel, GPU bandwidth, and a thread timeline read the same frame drop from three angles — so you optimize the right subsystem instead of guessing.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A dropped frame in a modern Unity game rarely has a single cause. Higher-fidelity art pushes Shader cost up, more textures increase GPU memory bandwidth, and heavier logic spreads work across threads. A stutter can come from any of these, and optimizing the wrong one yields no frame-time improvement at all.&lt;/p&gt;

&lt;p&gt;GameOptim GOT Online's Overview mode adds two diagnostics that read the same frame from different angles: &lt;strong&gt;GPU Counter&lt;/strong&gt; for shader cost and memory bandwidth, and &lt;strong&gt;Timeline&lt;/strong&gt; for thread-level activity during a stutter. This article explains what each measures, how to read them, and how to decide which one your stutter belongs to.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A frame drop can come from &lt;strong&gt;GPU shader cost&lt;/strong&gt;, &lt;strong&gt;GPU memory bandwidth&lt;/strong&gt;, or &lt;strong&gt;thread blocking&lt;/strong&gt; — each needs a different fix.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cycles/Pixel&lt;/strong&gt; measures the average GPU clock cycles spent per pixel. High values usually mean the Shader is too complex; low values with a stutter point elsewhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPU bandwidth&lt;/strong&gt; measures per-frame read/write volume. Sustained high external read/write causes fast battery drain and is independent of shader complexity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timeline&lt;/strong&gt; visualizes up to 5 threads with parent and child function durations, so you can see thread count, queueing, idle states, and inter-thread waits during the exact stutter frame.&lt;/li&gt;
&lt;li&gt;GPU Counter data is currently available on devices with supported &lt;strong&gt;Mali&lt;/strong&gt; chips; check device compatibility before reading absence as a finding.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Does "GPU Is Slow" Actually Mean?
&lt;/h2&gt;

&lt;p&gt;"GPU pressure" is three separate things bundled into one complaint. Each has a different symptom and a different fix.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Subsystem&lt;/th&gt;
&lt;th&gt;What it measures&lt;/th&gt;
&lt;th&gt;Symptom when overloaded&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cycles/Pixel&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Average GPU clock cycles per pixel&lt;/td&gt;
&lt;td&gt;Shader complexity exceeds per-pixel budget; frame time grows with screen complexity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GPU bandwidth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per-frame total read/write volume&lt;/td&gt;
&lt;td&gt;Sustained high load → fast battery drain, thermal throttling, eventual stutter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Thread timeline&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Activity across CPU threads during a frame&lt;/td&gt;
&lt;td&gt;Threads idle, queued, or waiting on each other; stutter caused by blocking, not raw compute&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These are independent. A game can have low Cycles/Pixel and still drop frames because threads are blocking. A game can have expensive shaders and a clean timeline. The new GOT Online features let you read each separately so you do not optimize one to fix the other.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cycles/Pixel: Reading Shader Complexity
&lt;/h2&gt;

&lt;p&gt;Cycles/Pixel is the average number of GPU clock cycles consumed per rendered pixel. Shader complexity is the dominant factor: when a scene's shaders are complex, the GPU spends many cycles per pixel evaluating them, GPU time rises, and the frame stutters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to read it:&lt;/strong&gt; Use Cycles/Pixel under GPU shading to identify scenes with high cycle counts, then judge whether the scene's GPU pressure is caused by shader complexity. If the cycles value is high and tracks with shader-heavy scenes, shader simplification is the right lever. If the cycles value is low but the frame still stutters, shader cost is not the cause — look at bandwidth or the thread timeline instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Cycles/Pixel does not tell you:&lt;/strong&gt; It cannot distinguish between a few very expensive pixels and many moderately expensive ones, and it says nothing about memory traffic. Pair it with bandwidth data before deciding.&lt;/p&gt;

&lt;h2&gt;
  
  
  GPU Bandwidth: Reading Memory Traffic
&lt;/h2&gt;

&lt;p&gt;GPU bandwidth, like CPU bandwidth, is a major contributor to chip power consumption. When the GPU performs sustained high-load external read/write operations, power draw rises sharply.&lt;/p&gt;

&lt;p&gt;The GPU bandwidth module in GOT Online reports the &lt;strong&gt;total per-frame read/write bandwidth&lt;/strong&gt; across the test. Use it to locate scenes where bandwidth is high, identify what is driving the traffic, and run a follow-up test after any changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to read it:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A scene with high bandwidth but normal Cycles/Pixel points at memory traffic — texture streaming, render-target copies, or excessive buffer uploads — rather than shader compute.&lt;/li&gt;
&lt;li&gt;A scene with both high bandwidth and high cycles confirms a GPU-heavy scene that needs work on both fronts.&lt;/li&gt;
&lt;li&gt;Bandwidth is also a thermal signal: sustained high values lead to throttling and stutter even when raw frame time looks acceptable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Timeline: Reading Thread Activity During a Stutter
&lt;/h2&gt;

&lt;p&gt;Overview mode already supported stutter analysis through call-stacks. The new Timeline module adds a time-ordered view so the sequence of events is visible at a glance.&lt;/p&gt;

&lt;p&gt;Timeline shows the main thread and up to 4 sub-threads (5 total). Under each thread, both parent and child functions are visible, and the length of each function's time bar represents its duration — the longer the bar, the more time that function consumed near that frame.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the Timeline answers:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many threads were active during the stutter frame.&lt;/li&gt;
&lt;li&gt;What each thread was executing and for how long.&lt;/li&gt;
&lt;li&gt;Whether threads were queued behind one another.&lt;/li&gt;
&lt;li&gt;Whether any thread was idle or waiting on another thread to finish.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes thread-level bottlenecks visible in a way a call-stack cannot. A call-stack tells you what one function did; a Timeline tells you whether another thread was the actual reason the frame did not complete on time.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can You Tell Which Subsystem Is Causing the Stutter?
&lt;/h2&gt;

&lt;p&gt;Work through the three signals in this order:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;If you see&lt;/th&gt;
&lt;th&gt;The cause is likely&lt;/th&gt;
&lt;th&gt;What to optimize&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cycles/Pixel high, bandwidth low, timeline clean&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Shader complexity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Reduce shader cost, simplify passes, optimize per-pixel work&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bandwidth high, cycles normal, timeline clean&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Memory traffic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Reduce texture streaming, render-target copies, buffer uploads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cycles and bandwidth normal, timeline shows idle/waiting threads&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Thread blocking&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Re-order work, remove unnecessary waits, balance load across threads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cycles high and bandwidth high&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Combined GPU load&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Address both, starting with whichever has the larger headroom gap&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A stutter that matches none of these rows may be CPU-side logic or input handling — the new modules do not cover that, and you should check the existing stutter call-stacks instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Should You Check First?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Confirm device compatibility.&lt;/strong&gt; GPU Counter data requires a supported Mali chip. If Cycles/Pixel and bandwidth are absent, it is a device limitation, not a zero reading.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start with the stutter frame.&lt;/strong&gt; Open Timeline and look at the exact frame that dropped. Thread activity at that moment tells you whether the problem is compute, memory, or blocking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read Cycles/Pixel next.&lt;/strong&gt; If the dropped frame also has high cycles, shader cost is involved.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read bandwidth for the same frame.&lt;/strong&gt; If bandwidth spiked too, memory traffic is part of the cause.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Correlate across the test.&lt;/strong&gt; A one-frame spike is different from a scene-wide trend. Check whether the high values persist through the scene or appear only in one frame.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What Should You Avoid?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Do not treat a missing GPU Counter reading as zero.&lt;/strong&gt; On unsupported devices the data is simply unavailable. Verify chip support first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not optimize shaders when the timeline shows thread waiting.&lt;/strong&gt; Shader work has no effect on a CPU-side thread-blocking stutter.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not reduce bandwidth if the cycles value is the real driver.&lt;/strong&gt; Cutting texture resolution will not lower Cycles/Pixel if the shader itself is the cost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not read a single frame in isolation.&lt;/strong&gt; Confirm the signal holds across the scene before making changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GPU pressure splits into &lt;strong&gt;Cycles/Pixel&lt;/strong&gt; (shader cost), &lt;strong&gt;bandwidth&lt;/strong&gt; (memory traffic), and &lt;strong&gt;thread blocking&lt;/strong&gt; (timeline) — independent signals requiring different fixes.&lt;/li&gt;
&lt;li&gt;High &lt;strong&gt;Cycles/Pixel&lt;/strong&gt; means shaders are doing too much per pixel. Low cycles with a stutter means the cause is elsewhere.&lt;/li&gt;
&lt;li&gt;High &lt;strong&gt;bandwidth&lt;/strong&gt; drives power draw and thermal throttling, even when frame time looks fine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timeline&lt;/strong&gt; reveals thread count, queueing, idle states, and inter-thread waits — the only way to see a blocking bottleneck.&lt;/li&gt;
&lt;li&gt;GPU Counter is available on supported &lt;strong&gt;Mali&lt;/strong&gt; devices; absence is a compatibility note, not a zero.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why is my Cycles/Pixel high but my game looks fine?&lt;/strong&gt;&lt;br&gt;
Cycles/Pixel measures shader cost per pixel, not visual quality. High values mean the GPU spends many cycles evaluating shaders, which can cause stutter even if the output looks correct. Simplify shaders or reduce overdraw to bring it down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does high GPU bandwidth cause stuttering directly?&lt;/strong&gt;&lt;br&gt;
Not always immediately. Sustained high bandwidth raises power draw and temperature, which leads to thermal throttling and eventual stutter. It also competes with other memory traffic, so spikes can coincide with frame drops.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How many threads does the Timeline show?&lt;/strong&gt;&lt;br&gt;
Up to 5 — the main thread plus 4 sub-threads. Within each thread, both parent and child functions are shown with duration bars.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does an idle thread in the Timeline mean?&lt;/strong&gt;&lt;br&gt;
A thread that is idle or waiting for another thread to finish means the stutter is likely a blocking issue, not a compute shortage. Re-ordering work or removing the wait is more effective than adding more CPU tasks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My device does not show GPU Counter data. Is that a bug?&lt;/strong&gt;&lt;br&gt;
GPU Counter currently supports devices with certain Mali chips. If the data is absent, verify that your device uses a supported chip; otherwise the reading is simply unavailable, not zero.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gpu</category>
      <category>performance</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>How Do You Find the Lua Function That Is Actually Costing You Frame Time?</title>
      <dc:creator>GameOptim</dc:creator>
      <pubDate>Wed, 04 Nov 2026 06:55:51 +0000</pubDate>
      <link>https://dev.to/gameoptim/how-do-you-find-the-lua-function-that-is-actually-costing-you-frame-time-27mf</link>
      <guid>https://dev.to/gameoptim/how-do-you-find-the-lua-function-that-is-actually-costing-you-frame-time-27mf</guid>
      <description>&lt;p&gt;&lt;strong&gt;A Lua entry in the top-20 cost list is the start of the investigation, not the answer. Three stack views plus a reversed call tree point you at the leaf function worth fixing.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Lua rarely shows up in a Unity performance report as one big number. It shows up as a handful of function names inside the logic-code cost ranking, and the expensive part is usually not the function listed there — it is a leaf several levels down its call stack.&lt;/p&gt;

&lt;p&gt;The practical workflow is short: open the GOT Online Lua report's &lt;strong&gt;Code Efficiency → CPU Time&lt;/strong&gt; page, choose the stack view that matches the question you are asking (whole-session, single-scene, or single-frame), then reverse the stack so the deepest and most expensive children surface first. This article walks through that sequence, explains the Lua function naming format the report uses, and covers the one test setting that silently breaks the whole analysis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Lua cost appears in reports as individual functions in the top-20 logic cost list, not as a single aggregate figure.&lt;/li&gt;
&lt;li&gt;The report offers three stack views: &lt;strong&gt;overall cost&lt;/strong&gt;, &lt;strong&gt;specified scene&lt;/strong&gt;, and &lt;strong&gt;any single frame&lt;/strong&gt;. Each answers a different question; using the wrong one sends you to the wrong function.&lt;/li&gt;
&lt;li&gt;Lua functions are identified as &lt;strong&gt;&lt;code&gt;X@Y:Z&lt;/code&gt;&lt;/strong&gt; — function name, defining file, defining line. When the name cannot be resolved, &lt;code&gt;X&lt;/code&gt; becomes &lt;code&gt;unknown&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;When Lua runs as &lt;strong&gt;bytecode&lt;/strong&gt;, the line number &lt;code&gt;Z&lt;/code&gt; is always &lt;code&gt;0&lt;/code&gt;. Test with Lua source if you want line-level attribution.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reverse stack analysis&lt;/strong&gt; reorders the cost stack so deep sub-functions that actually consume the time appear on top, instead of forcing you to expand dozens of levels by hand.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Is the Core Problem?
&lt;/h2&gt;

&lt;p&gt;When Lua usage grows in a commercial project, CPU cost spreads across many small functions rather than concentrating in one obviously slow place. In a report, that looks like several Lua functions mixed into the top-20 logic cost list — enough to know Lua is involved, not enough to know where to change code.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv5g4phis49rss0j30xaj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv5g4phis49rss0j30xaj.png" alt=" " width="799" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqveanjmt1ak184r160b9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqveanjmt1ak184r160b9.png" alt=" " width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The cost hides for two reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The entry function is not the expensive function.&lt;/strong&gt; A Lua call often passes through wrappers, dispatch tables, and utility layers before reaching the function that does the work. The top-level name accumulates cost; the leaf generates it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aggregate and peak are different measurements.&lt;/strong&gt; A function can dominate total session cost while never appearing in the frame where the game stuttered, and vice versa. Locating one does not locate the other.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why Does the Cost Hide in the Call Stack?
&lt;/h2&gt;

&lt;p&gt;A stack trace orders calls from the outermost caller to the innermost callee. Read top-down, the first entries are the ones you recognize — event handlers, update loops, framework entry points — and they carry the largest accumulated totals simply because everything below them rolls up into their number.&lt;/p&gt;

&lt;p&gt;The actual work sits at the bottom. To see it in the default view, you expand frame after frame, often dozens of levels deep, and the numbers you are comparing are already diluted by sibling branches. That is the structural reason a "Lua is slow" finding stalls: the report is correct, but the ordering hides the answer.&lt;/p&gt;

&lt;p&gt;Reversing the stack fixes the ordering. Instead of reading caller → callee, you read callee → caller, so the deepest sub-function with the highest self-cost lands at the top of the view. The bottleneck becomes visible without manual expansion.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Is a Lua Function Identified in the Report?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk69vd55i5zx5zen3s4is.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk69vd55i5zx5zen3s4is.png" alt=" " width="800" height="783"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every Lua entry carries a name in a fixed format that maps it back to source:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Part&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Function name&lt;/td&gt;
&lt;td&gt;Falls back to &lt;code&gt;unknown&lt;/code&gt; when it cannot be resolved&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Y&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;File where the function is defined&lt;/td&gt;
&lt;td&gt;The script location, not the call site&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Z&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Line where the function is defined&lt;/td&gt;
&lt;td&gt;Always &lt;code&gt;0&lt;/code&gt; under bytecode execution&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;X@Y:Z&lt;/code&gt; is enough to search your codebase directly: file plus line lands you on the definition, and the function name confirms it. This is why the format matters more than the visual stack — it converts a profiler row into a code location.&lt;/p&gt;

&lt;p&gt;The bytecode caveat is the one that trips teams up. If the Lua scripts are shipped as bytecode, &lt;code&gt;Z&lt;/code&gt; is &lt;code&gt;0&lt;/code&gt; for everything, and you lose line-level attribution entirely. The recommendation is to run the test with Lua source wherever possible, so the stack data stays resolvable.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can You Tell Whether the Function Is Actually a Problem?
&lt;/h2&gt;

&lt;p&gt;Match the stack view to the question. Each view isolates a different kind of cost, and the answers do not transfer between them.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;View&lt;/th&gt;
&lt;th&gt;Question it answers&lt;/th&gt;
&lt;th&gt;Use it when&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Overall CPU cost stack&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Which Lua functions accumulate the most cost across the whole session&lt;/td&gt;
&lt;td&gt;Building the hotspot shortlist at the start&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Specified-scene stack&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Which Lua functions dominate in one particular scene&lt;/td&gt;
&lt;td&gt;Cost differs by scene, and you want to target one&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Single-frame cost stack&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Which Lua functions consumed time in the exact frame where cost peaked&lt;/td&gt;
&lt;td&gt;Explaining a specific spike or stutter&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Three signals confirm that a function is a genuine target rather than noise:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It appears &lt;strong&gt;high in the reversed overall stack&lt;/strong&gt;, meaning its own cost is large rather than inherited from children.&lt;/li&gt;
&lt;li&gt;It &lt;strong&gt;reappears in the per-scene view&lt;/strong&gt; for the scene that carries the memory or frame-time pressure.&lt;/li&gt;
&lt;li&gt;It &lt;strong&gt;positions itself in the peak frame's stack&lt;/strong&gt;, so the aggregate number and the visible symptom agree.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a function only satisfies the first signal, you have found volume, not a bottleneck. If it only satisfies the third, you have found a one-off spike, not a pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Should You Check First?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Open the Code Efficiency → CPU Time page and confirm Lua entries exist.&lt;/strong&gt; If Lua does not appear in the top-20 logic cost list, this workflow has nothing to target yet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start with the overall stack to build a shortlist.&lt;/strong&gt; Do not optimize from this list; use it to pick candidates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reverse the stack before judging any candidate.&lt;/strong&gt; The entry with the biggest number in the default order is frequently the caller, not the cause.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Record the &lt;code&gt;X@Y:Z&lt;/code&gt; identifier for each candidate.&lt;/strong&gt; File and line are what make the finding actionable in code review.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confirm the test ran on source, not bytecode.&lt;/strong&gt; If every &lt;code&gt;Z&lt;/code&gt; is &lt;code&gt;0&lt;/code&gt;, fix the test setup before drawing conclusions — the data is coarse by construction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Re-check the candidate in the scene view and the peak-frame view.&lt;/strong&gt; A function that survives all three is a real target.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What Should You Optimize?
&lt;/h2&gt;

&lt;p&gt;Optimize the leaf, then the path that reaches it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The leaf function itself&lt;/strong&gt; is where the self-cost sits. The reversed stack identifies it; the &lt;code&gt;X@Y:Z&lt;/code&gt; identifier locates it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The call frequency of that path&lt;/strong&gt; decides whether the total cost is a problem. The per-frame stack shows what one call costs; the aggregate stack shows how often it happens. A cheap function on a hot path costs more than an expensive function called twice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The scene where it concentrates&lt;/strong&gt; tells you whether the fix is local (a scene-specific feature) or systemic (a shared utility used everywhere).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each change should be re-measured with the same view that produced the finding. A fix that lowers aggregate cost but leaves the peak-frame stack unchanged has moved volume without removing the spike.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Should You Avoid?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Do not optimize the top entry of the default stack.&lt;/strong&gt; It inherits cost from everything beneath it; changing it usually means changing design, not code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not profile bytecode builds and expect line numbers.&lt;/strong&gt; &lt;code&gt;Z = 0&lt;/code&gt; is a test configuration result, not a report bug.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not expand the stack by hand to find the bottom.&lt;/strong&gt; Toggle the reversed view instead; dozens of manual expansions is how bottlenecks get missed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not treat an aggregate hotspot as a frame-time problem without checking the peak frame.&lt;/strong&gt; Total cost and peak cost point at different code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Practical Recommendations
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;th&gt;What to inspect&lt;/th&gt;
&lt;th&gt;How to judge&lt;/th&gt;
&lt;th&gt;What to change&lt;/th&gt;
&lt;th&gt;What to re-measure&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lua appears in the cost list but you cannot name the culprit&lt;/td&gt;
&lt;td&gt;Reversed overall stack&lt;/td&gt;
&lt;td&gt;Highest self-cost at the deepest level&lt;/td&gt;
&lt;td&gt;That leaf function&lt;/td&gt;
&lt;td&gt;Overall stack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost is concentrated in one scene&lt;/td&gt;
&lt;td&gt;Specified-scene stack&lt;/td&gt;
&lt;td&gt;Same function tops the scene view&lt;/td&gt;
&lt;td&gt;Scene-scoped logic&lt;/td&gt;
&lt;td&gt;Scene view plus overall&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost peaks only in one frame&lt;/td&gt;
&lt;td&gt;Single-frame stack&lt;/td&gt;
&lt;td&gt;Function present in the peak frame&lt;/td&gt;
&lt;td&gt;The call path taken in that frame&lt;/td&gt;
&lt;td&gt;Peak-frame view&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Line numbers are all &lt;code&gt;0&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Test script delivery&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Z&lt;/code&gt; equals &lt;code&gt;0&lt;/code&gt; across entries&lt;/td&gt;
&lt;td&gt;Run the test on Lua source&lt;/td&gt;
&lt;td&gt;Naming resolved to file and line&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A candidate looks large but changes nothing when tuned&lt;/td&gt;
&lt;td&gt;Peak-frame view&lt;/td&gt;
&lt;td&gt;Function absent from the spike frame&lt;/td&gt;
&lt;td&gt;Investigate the actual spike frame&lt;/td&gt;
&lt;td&gt;Stutter metric, not total cost&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Lua cost in a report is a list of functions, and the listed function is often the caller rather than the cause.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reverse stack analysis&lt;/strong&gt; surfaces the deep sub-function that actually holds the cost.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;X@Y:Z&lt;/code&gt; — name, file, line — is the bridge from a profiler row to a code location.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bytecode execution forces &lt;code&gt;Z&lt;/code&gt; to &lt;code&gt;0&lt;/code&gt;.&lt;/strong&gt; Test with source when line-level attribution matters.&lt;/li&gt;
&lt;li&gt;Overall, per-scene, and per-frame stacks answer different questions; a real bottleneck shows up in the ones that match your symptom.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What does the &lt;code&gt;X@Y:Z&lt;/code&gt; format in a Lua stack entry mean?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;X&lt;/code&gt; is the function name, &lt;code&gt;Y&lt;/code&gt; is the file where the function is defined, and &lt;code&gt;Z&lt;/code&gt; is the line number of its definition. If the name cannot be resolved, &lt;code&gt;X&lt;/code&gt; becomes &lt;code&gt;unknown&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is the line number always 0 in my Lua data?&lt;/strong&gt;&lt;br&gt;
Because the scripts are running as bytecode. Under bytecode execution the line value is always &lt;code&gt;0&lt;/code&gt;, so run the test with Lua source to get usable line-level attribution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should I use the overall stack or the single-frame stack?&lt;/strong&gt;&lt;br&gt;
Use the overall stack to find which functions accumulate cost across the session, and the single-frame stack to explain a specific spike or stutter. A function can be large in total while never appearing in the frame you are investigating.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why does reversing the stack make the bottleneck easier to find?&lt;/strong&gt;&lt;br&gt;
The default order lists callers above callees, so entry points carry inflated totals. Reversed, the deepest callee with the highest self-cost appears first, which removes the need to expand dozens of levels manually.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is a function that tops the overall cost list necessarily the one to optimize?&lt;/strong&gt;&lt;br&gt;
Not necessarily. It may simply be a caller that aggregates everything beneath it. Confirm that the self-cost is high and that it also appears in the scene or peak-frame view before treating it as a target.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>lua</category>
      <category>performance</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>How Can You Tell Whether a Unity Crash Is From GPU Memory, Resource Footprint, or Mono Heap Retention?</title>
      <dc:creator>GameOptim</dc:creator>
      <pubDate>Mon, 02 Nov 2026 08:02:58 +0000</pubDate>
      <link>https://dev.to/gameoptim/how-can-you-tell-whether-a-unity-crash-is-from-gpu-memory-resource-footprint-or-mono-heap-1cgh</link>
      <guid>https://dev.to/gameoptim/how-can-you-tell-whether-a-unity-crash-is-from-gpu-memory-resource-footprint-or-mono-heap-1cgh</guid>
      <description>&lt;p&gt;&lt;strong&gt;One high memory number hides three different root causes. GameOptim GOT Online's new PSS GPU trend, per-resource snapshots, and IL2CPP heap dumps split that single signal into three diagnosable metrics — so you can fix the right subsystem instead of guessing.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Memory pressure crashes are one of the most common reasons a Unity build fails device certification or gets refunded on release. The frustrating part is that "memory is high" is almost never the whole story — GPU memory, general resource footprint, and Mono heap retention all contribute to the final OOM kill, and fixing the wrong one wastes days of iteration.&lt;/p&gt;

&lt;p&gt;GameOptim GOT Online's latest release adds three new diagnostics that let you read each subsystem separately, instead of guessing from a single total memory number. This article explains what each new metric actually measures, how to read it correctly, and the caveats you need to know before acting on the data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A single high memory value is useless unless you split it into &lt;strong&gt;PSS GPU memory&lt;/strong&gt;, &lt;strong&gt;resource memory&lt;/strong&gt;, and &lt;strong&gt;Mono Reserved&lt;/strong&gt; — each points to a different subsystem with a different root cause.&lt;/li&gt;
&lt;li&gt;PSS GPU memory, newly added to GOT Online's Overview mode, shows the rendering memory the graphics driver reports; Android 10 and 11 refresh this value only every 5 minutes, so the curve appears stepped.&lt;/li&gt;
&lt;li&gt;The new &lt;strong&gt;Memory Usage&lt;/strong&gt; page combines an overview table (PSS, Mono Reserved, resource, Lua heap) with per-resource breakdowns and frame-level snapshots marked on the time axis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IL2CPP Mono heap snapshots&lt;/strong&gt; are now available without a separate Mono build, provided you build with Unity 2019.4+ and &lt;strong&gt;Script Debugging&lt;/strong&gt; enabled.&lt;/li&gt;
&lt;li&gt;Sampling strategy matters: manual resource snapshots capture every resource in a frame, while periodic snapshots and Resource-mode data have lower resolution by design to keep instrumentation overhead acceptable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Does "High Memory" Actually Mean in Unity?
&lt;/h2&gt;

&lt;p&gt;Unity games draw memory from three distinct pools, and each pool grows for different reasons. Fixing a Mono leak with asset compression, or vice versa, never works.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Subsystem&lt;/th&gt;
&lt;th&gt;What it measures&lt;/th&gt;
&lt;th&gt;Typical failure mode&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PSS GPU Memory&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Rendering memory reported by the graphics driver — textures, meshes, driver libraries&lt;/td&gt;
&lt;td&gt;OOM kills on Android when GPU memory spikes past the device threshold&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Resource Memory&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Total memory consumed by textures, meshes, animations, audio, and 7 other categories&lt;/td&gt;
&lt;td&gt;Scene transitions that push total resources past device limits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Mono Reserved&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Managed heap capacity held by the Mono runtime&lt;/td&gt;
&lt;td&gt;Slow growth over a session that eventually exhausts process memory&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These three pools are independent. A game with moderate PSS can still crash from GPU memory; a game with stable resource memory can still leak Mono references. The new GOT Online features let you inspect each one without running three separate test passes.&lt;/p&gt;

&lt;h2&gt;
  
  
  PSS GPU Memory: Reading the Driver's Number
&lt;/h2&gt;

&lt;p&gt;The new PSS GPU memory trend appears in the Overview mode's &lt;strong&gt;Runtime Info&lt;/strong&gt; page. GPU memory is the memory consumed by rendering resources at the driver level — texture data, mesh buffers, and memory allocated by the libraries that parse those resources. Unlike process PSS memory, this value is reported directly by the graphics driver rather than by the OS memory manager.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fabjopcof3zr97q9aa4x7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fabjopcof3zr97q9aa4x7.png" alt=" " width="799" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When GPU memory rises near the device limit, the kernel kills the process — so tracking this number is critical for crash-risk management alongside PSS memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important caveat for Android 10 and Android 11:&lt;/strong&gt; Due to platform-level restrictions, these OS versions refresh the GPU PSS value only once every 5 minutes after boot. On those devices the curve appears as a step function, and a large jump at frame N actually reflects changes that accumulated over the preceding 5 minutes. When GPU memory spikes appear in reports from Android 10/11, trace back through events in the prior 5-minute window before assigning blame to a single frame.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Memory Usage Page: One Table, Three Questions
&lt;/h2&gt;

&lt;p&gt;GOT Online's Overview mode now includes a &lt;strong&gt;Memory Usage&lt;/strong&gt; page that consolidates memory diagnostics previously scattered across separate reports. The page is organized into two layers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 1: The Overview Table
&lt;/h3&gt;

&lt;p&gt;The overview table plots &lt;strong&gt;PSS memory&lt;/strong&gt;, &lt;strong&gt;Reserved Mono&lt;/strong&gt;, and &lt;strong&gt;total resource memory&lt;/strong&gt; on one time axis. When Lua testing is enabled in Overview mode, Lua heap memory is added as a fourth curve. Resource memory here is the sum of all resource memory collected during the test.&lt;/p&gt;

&lt;p&gt;GameOptim SDK samples data at five points by default — test start, every 1,000 frames, scene transitions, test end, and manual resource snapshots via the &lt;strong&gt;Dump&lt;/strong&gt; operation. Only manual Dumps capture every resource in the current frame with full detail.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk3lyu4xq1dp9b2xq97mq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk3lyu4xq1dp9b2xq97mq.png" alt=" " width="533" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The default view shows three curves — &lt;strong&gt;PSS memory&lt;/strong&gt;, &lt;strong&gt;Reserved Mono&lt;/strong&gt;, and &lt;strong&gt;total resource memory&lt;/strong&gt; — with all resource-object snapshot frames marked on the horizontal axis.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhyvmdyowfz3ckg3iico9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhyvmdyowfz3ckg3iico9.png" alt=" " width="800" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resource-mode caveat:&lt;/strong&gt; When Resource mode is enabled alongside Overview mode, the SDK collects detailed per-resource data. To keep instrumentation overhead acceptable, different resource categories are sampled on different frames. The resulting total resource memory is a simulated sum with a 60-frame step — lower accuracy, and hidden by default in the table.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance caveat:&lt;/strong&gt; Running Overview mode with Resource mode enabled introduces measurable overhead (lower frame rate, stutter during collection). Do not use this combination for general gameplay performance analysis — it's specifically for resource memory diagnosis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 2: Per-Resource Breakdown and Snapshots
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Resource Memory Usage&lt;/strong&gt; table breaks resource memory into 11 categories: textures, meshes, animations, audio, and seven others. Each category gets its own trend line so you can see exactly which resource type is driving total memory pressure in each scene, and quickly judge which resource type is responsible for memory pressure in each scene.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo59ixck85aqw6ga3f62l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo59ixck85aqw6ga3f62l.png" alt=" " width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Selecting a resource snapshot frame (in non-Resource mode) or any frame (in Resource mode) generates two artifacts below the table: a pie-chart preview showing resource-type memory share at that frame, and the corresponding resource detail data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbziaw4zt6slomzzudgsv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbziaw4zt6slomzzudgsv.png" alt=" " width="800" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The resource-object snapshot module does two things at once: it shows the memory-share pie chart of each resource type at the selected frame, and lists every resource type in a table sorted by memory usage (largest first). For each type the table shows the quantity, memory usage, and a recommended-value flag — items exceeding the recommended value are highlighted in red so you can immediately locate categories that need attention.&lt;/p&gt;

&lt;p&gt;Clicking the operation column in the table jumps directly to the corresponding tab in the Resource Memory page for deeper analysis. In the Resource Memory page, resource-object snapshot frames are also marked, so selecting any snapshot frame pulls up the detailed resource information for that moment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feyozs137zntlq0w9u15w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feyozs137zntlq0w9u15w.png" alt=" " width="800" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Memory Usage page also supports &lt;strong&gt;comparison mode&lt;/strong&gt;: toggle it on from the bottom right, select any two snapshot frames (non-Resource mode) or any two frames (Resource mode), and the page shows the per-resource memory delta between them — quantity and size for every resource type.&lt;/p&gt;

&lt;h2&gt;
  
  
  IL2CPP Mono Heap Snapshots: No Separate Mono Build Required
&lt;/h2&gt;

&lt;p&gt;For managed memory analysis, GOT Online adds two new pages under &lt;strong&gt;Heap Leak Analysis&lt;/strong&gt;: &lt;strong&gt;Resident Heap Allocation Functions&lt;/strong&gt; and &lt;strong&gt;Heap Object Snapshot&lt;/strong&gt;. These sit alongside the existing IL2CPP Mono heap allocation data collection, which requires Unity 2019.4 or later with &lt;strong&gt;Script Debugging&lt;/strong&gt; enabled at build time.&lt;/p&gt;

&lt;p&gt;Dump rules are configured before the test run — snapshots are collected either at a fixed frame interval or on manual trigger.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reading the Heap Object Snapshot
&lt;/h3&gt;

&lt;p&gt;Developers can use the bar chart in the &lt;strong&gt;Heap Object Snapshot&lt;/strong&gt; page to quickly identify which scenes retain heap memory worth optimizing. The chart supports two dimensions — &lt;strong&gt;heap object size&lt;/strong&gt; and &lt;strong&gt;heap object count&lt;/strong&gt; — so you can see whether retention comes from a small number of large objects or a large number of small ones.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx7z1copa5st2svpg9lro.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx7z1copa5st2svpg9lro.png" alt=" " width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Heap objects split into two parts: &lt;strong&gt;Managed Objects&lt;/strong&gt; and &lt;strong&gt;memory fragmentation&lt;/strong&gt;. Fragmentation itself splits further into &lt;strong&gt;free active memory&lt;/strong&gt; (used first during allocation) and &lt;strong&gt;free fragment memory&lt;/strong&gt; (used only when active memory is insufficient). Allocation always consumes from free active memory before falling back to fragments.&lt;/p&gt;

&lt;p&gt;Below the bar chart, the page shows summary stats for the selected frame: total Managed Object size, total type count, total object count, and fragmentation ratio. On the right, a pie chart shows the share of the top 10 object types by memory usage, with the remainder grouped as "other" — giving you an immediate view of where Mono memory is concentrated so you can lock in on the bottleneck.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp1klxa5810cth8gbx82a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp1klxa5810cth8gbx82a.png" alt=" " width="800" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Below the pie chart sits the object-type table, which lists every object type in the selected frame along with its size, share, and object count. Expanding any object type reveals every function that allocated that type, and the inverse call path from those functions upward to your code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft15z9dwuxzd1es1xrbdi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft15z9dwuxzd1es1xrbdi.png" alt=" " width="800" height="266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the critical diagnostic step: the call path tells you exactly where in your code the allocation originates, so you can search for the sub-function and fix the source rather than masking the symptom.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sampling Caveats That Change How You Read the Data
&lt;/h2&gt;

&lt;p&gt;Three properties of GameOptim's sampling strategy are easy to overlook but directly affect what the data means:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Resource-mode step size.&lt;/strong&gt; Detailed per-resource data is collected every 60 frames, not every frame. The simulated total curve has deliberate gaps. Do not treat a frame-to-frame dip in the simulated curve as evidence that memory was released.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dump triggers.&lt;/strong&gt; Only manual &lt;strong&gt;Dump&lt;/strong&gt; operations capture every resource in the frame. Periodic samples (start, every 1,000 frames, scene transitions, end) are partial snapshots. If you need a complete view of resource state at a specific moment, trigger a manual Dump.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Android 10/11 GPU PSS refresh.&lt;/strong&gt; As noted above, GPU PSS values on these devices update every 5 minutes. A spike at frame N is not necessarily caused by an event at frame N.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PSS GPU memory, resource memory, and Mono Reserved are three independent signals.&lt;/strong&gt; Each one points to a different subsystem; no single number can diagnose a crash.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Android 10/11 users&lt;/strong&gt; must account for the 5-minute GPU PSS refresh rate when reading GPU memory spikes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IL2CPP Mono analysis&lt;/strong&gt; now works from GOT Online — no separate Mono build needed, provided you build with Script Debugging enabled in Unity 2019.4+.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual Dump captures every resource&lt;/strong&gt;; periodic samples do not. Use manual Dumps when you need a complete frame-level picture.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource mode + Overview mode&lt;/strong&gt; has meaningful performance overhead. Use it for resource diagnosis only, not for general gameplay performance measurement.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why does my Android 11 report show a single frame where GPU memory jumps by 200 MB?&lt;/strong&gt;&lt;br&gt;
Android 10 and 11 refresh the GPU PSS value only once every 5 minutes. The jump reflects changes accumulated over the preceding 5 minutes, not a single frame's workload.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I still need to build a separate Mono build to analyze heap retention?&lt;/strong&gt;&lt;br&gt;
No. On GOT Online, IL2CPP builds support Mono heap allocation data collection and snapshots, provided you build with Unity 2019.4 or later and have &lt;strong&gt;Script Debugging&lt;/strong&gt; enabled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The total resource memory in my Resource-mode test looks lower than I expected. Is the report wrong?&lt;/strong&gt;&lt;br&gt;
When Resource mode is enabled alongside Overview mode, total resource memory is a simulated sum with a 60-frame step and lower accuracy. It is hidden by default for this reason.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I compare memory usage between two scenes?&lt;/strong&gt;&lt;br&gt;
Use the comparison mode in the Resource Memory Usage table. Open comparison mode from the bottom right, select two snapshot frames, and the page shows the per-resource memory delta between them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should I always run with Resource mode enabled to get better data?&lt;/strong&gt;&lt;br&gt;
Resource mode introduces significant overhead (lower frame rate, stutter). Enable it only when you specifically need per-resource breakdowns; for general crash-risk assessment, Overview mode with the new PSS GPU and Mono data is sufficient.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>crash</category>
      <category>resources</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>How Large Should a Unity Mono Heap Be Before You Treat It as a Problem?</title>
      <dc:creator>GameOptim</dc:creator>
      <pubDate>Fri, 30 Oct 2026 10:49:26 +0000</pubDate>
      <link>https://dev.to/gameoptim/how-large-should-a-unity-mono-heap-be-before-you-treat-it-as-a-problem-ja0</link>
      <guid>https://dev.to/gameoptim/how-large-should-a-unity-mono-heap-be-before-you-treat-it-as-a-problem-ja0</guid>
      <description>&lt;p&gt;&lt;strong&gt;Heap size on its own is a weak signal. Check Reserved versus Used, whether allocation keeps growing across a session, and whether GC stutter frames line up with your allocation pattern — before you change any code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A large Mono heap in a Unity game is not automatically a leak, and it is not automatically worth optimizing. The heap number tells you how much memory the managed runtime has reserved. Whether that number is a problem depends on three separate facts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How much of the heap is actually holding live data (&lt;strong&gt;Mono Used&lt;/strong&gt;) versus merely reserved (&lt;strong&gt;Mono Reserved&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;Whether the value keeps growing across a session, or settles after the first scene.&lt;/li&gt;
&lt;li&gt;Whether managed allocation is producing GC stutter frames during normal gameplay.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;GameOptim's guidance treats a Mono heap above roughly &lt;strong&gt;80 MB&lt;/strong&gt; as a reason to collect Mono data in depth — not as a verdict that the project is leaking. The rest of this article explains how to separate those cases, what to inspect first, and which optimizations are actually worth doing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A high Mono heap value is a triage signal, not proof of a leak.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reserved&lt;/strong&gt; and &lt;strong&gt;Used&lt;/strong&gt; answer different questions: how much capacity the runtime holds, and how much of it is live. Read them together, never the larger one alone.&lt;/li&gt;
&lt;li&gt;Continuous managed allocation causes both memory growth and &lt;strong&gt;GC stutter&lt;/strong&gt;; forced collections such as &lt;code&gt;GC.Collect&lt;/code&gt; and &lt;code&gt;UnloadUnused&lt;/code&gt; show up as recurring stutter points in profile data.&lt;/li&gt;
&lt;li&gt;Lua objects that hold references to Mono objects can keep managed memory alive, so a Lua-side reference graph can look exactly like a Mono leak.&lt;/li&gt;
&lt;li&gt;On IL2CPP, Mono heap data can be collected with SDK 2.4.5 or later and &lt;strong&gt;Script Debugging&lt;/strong&gt; enabled, so producing a separate Mono build is no longer a prerequisite for this analysis.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Is the Core Problem?
&lt;/h2&gt;

&lt;p&gt;Unity's Mono heap is the managed memory area used by C# objects, strings, and the runtime's own bookkeeping. Teams usually arrive at this question after seeing one of two symptoms: the heap value in a report looks large, or the game stutters at intervals that no rendering change seems to fix.&lt;/p&gt;

&lt;p&gt;These are different problems wearing the same number:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;What it describes&lt;/th&gt;
&lt;th&gt;Why it matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Mono Reserved&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The heap capacity the runtime holds&lt;/td&gt;
&lt;td&gt;A high value with low usage means capacity, not retention&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Mono Used&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Memory currently allocated to live managed objects&lt;/td&gt;
&lt;td&gt;Growth here usually means something is still referenced&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Allocation churn&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;How fast new managed memory is being allocated and dropped&lt;/td&gt;
&lt;td&gt;Drives GC frequency, and therefore stutter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Leak&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Live objects that should have been released but are still referenced&lt;/td&gt;
&lt;td&gt;Eventually exhausts memory and can crash the process&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A heap can be large and healthy (a big but stable live set), or moderate and unhealthy (a small live set that keeps growing). Optimization decisions made from the Reserved figure alone will frequently target the wrong subsystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does a Large Mono Heap Slow Down a Unity Game?
&lt;/h2&gt;

&lt;p&gt;Two mechanisms connect heap size to frame time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First, allocation triggers collection.&lt;/strong&gt; Every managed allocation adds to the heap; when the heap crosses a threshold, the runtime runs a garbage collection. That collection consumes CPU time inside a frame, which is why sustained allocation shows up as periodic frame-time spikes rather than a smooth slowdown. Reducing allocation frequency reduces the frequency of those spikes, independent of how large the heap currently is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second, reserved memory has a hard ceiling.&lt;/strong&gt; If a project leaks managed memory badly enough, the heap keeps expanding until the process runs out of memory and the game terminates. On constrained devices this can arrive well before the game looks "heavy" in a desktop profile.&lt;/p&gt;

&lt;p&gt;Collecting this data has its own cost, which is why sampling strategy matters. Instrumentation adds work at every probe point, so capturing everything on every frame risks distorting the very frame times you are trying to measure. GameOptim's memory modules therefore sample at key moments — the first frame of a test, every thousand frames, scene-transition frames, and the final frame — instead of recording continuously. Reading a report with that rhythm in mind prevents you from treating a sampling gap as a memory drop.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can You Tell Whether the Heap Is Actually a Problem?
&lt;/h2&gt;

&lt;p&gt;Compare the metrics against each other and against time. The combinations below separate a leak from a large-but-stable footprint.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Observation across a session&lt;/th&gt;
&lt;th&gt;Likely meaning&lt;/th&gt;
&lt;th&gt;Next check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Used&lt;/strong&gt; rises steadily and never returns&lt;/td&gt;
&lt;td&gt;Live objects are being retained&lt;/td&gt;
&lt;td&gt;Reference chain — including Lua-held references to Mono objects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Reserved&lt;/strong&gt; rises while &lt;strong&gt;Used&lt;/strong&gt; stays flat&lt;/td&gt;
&lt;td&gt;The heap expanded, but the retained object set did not&lt;/td&gt;
&lt;td&gt;Whether the expansion is bounded; it is not, by itself, evidence of a leak&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Reserved&lt;/strong&gt; and &lt;strong&gt;Used&lt;/strong&gt; both high but stable&lt;/td&gt;
&lt;td&gt;Large live footprint, stable workload&lt;/td&gt;
&lt;td&gt;Whether the device budget tolerates it; optimization is a trade-off decision, not a bug fix&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stutter frames cluster around allocation spikes&lt;/td&gt;
&lt;td&gt;GC pressure from allocation churn&lt;/td&gt;
&lt;td&gt;Allocation rate per frame, and any forced collection calls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stutter correlates with scene loads&lt;/td&gt;
&lt;td&gt;Load-time allocation, not steady-state&lt;/td&gt;
&lt;td&gt;Loading-path functions rather than gameplay allocation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;GameOptim's published guidance is to keep the Mono heap within about &lt;strong&gt;80 MB&lt;/strong&gt;, and to run a Mono-mode session for deeper allocation and leak analysis when the heap runs higher than that. Treat 80 MB as the point at which the question becomes worth a dedicated test, not as a pass/fail line: the acceptable ceiling is set by your target device and the rest of your memory budget.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Should You Check First?
&lt;/h2&gt;

&lt;p&gt;Work in this order; each step rules out a cheaper explanation before you spend effort on the next.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Confirm the build can report Mono data.&lt;/strong&gt; On IL2CPP, this requires SDK 2.4.5 or later and the &lt;strong&gt;Script Debugging&lt;/strong&gt; option enabled at build time. Without it, the absence of Mono data is a configuration issue, not a finding. Keep build settings identical between runs you intend to compare.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collect a session that includes real gameplay.&lt;/strong&gt; A session that only loads a scene cannot distinguish a live set from a leak. The sampling points — start frame, periodic samples, scene transitions, end frame — are what make growth visible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read Reserved and Used as a pair.&lt;/strong&gt; Establish whether the retainer is capacity or live objects before looking anywhere else.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check Lua-to-Mono references.&lt;/strong&gt; If Lua holds references to Mono objects, those objects are never released, and Mono Used climbs with no C# allocation in sight. Lua heap data and Mono object reference data answer this directly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check whether the stutter frames are collection frames.&lt;/strong&gt; &lt;code&gt;GC.Collect&lt;/code&gt; and &lt;code&gt;UnloadUnused&lt;/code&gt; appear as their own stutter categories, with duration, location, and call frequency. If your spikes belong to those categories, you are looking at collection cost, not at rendering or asset work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Only then look at loading-path functions.&lt;/strong&gt; &lt;code&gt;Shader.Parse&lt;/code&gt;, &lt;code&gt;Shader.CreateGPUProgram&lt;/code&gt;, &lt;code&gt;Instantiate&lt;/code&gt;, and &lt;code&gt;LoadingReadObject&lt;/code&gt; are the common load-time costs. If stutter happens during scene transitions rather than steady state, this is where the time is going.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What Should You Optimize?
&lt;/h2&gt;

&lt;p&gt;Prioritize by what the data showed, in this order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Retained objects first.&lt;/strong&gt; If Used grows and never drops, fix the reference that keeps the object alive — Lua references are the most common blind spot, because the C# side looks clean.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Allocation rate second.&lt;/strong&gt; If Used is stable but stutter follows allocation spikes, reduce per-frame managed allocation. You are targeting GC frequency, not heap size.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forced collection calls third.&lt;/strong&gt; If &lt;code&gt;GC.Collect&lt;/code&gt; or &lt;code&gt;UnloadUnused&lt;/code&gt; shows up as a stutter category, the call sites are in your own code. The data gives you the timing and frequency to judge whether the call is doing work at a moment the frame cannot afford.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Loading path last, and only if it matched the symptom.&lt;/strong&gt; Loading stutter is a different problem with different fixes; do not tune steady-state allocation to fix a scene-load spike.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each of these changes should be followed by a new collection run under the same conditions. Because sampling is periodic, a change that only shifts when allocation happens can look subtle in aggregate numbers while being obvious in the stutter frames.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Should You Avoid Optimizing Prematurely?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Do not treat the heap number as a diagnosis.&lt;/strong&gt; A large heap with a stable live set is a capacity decision, not a bug. Cutting it requires giving something up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not read Reserved as if it were Used.&lt;/strong&gt; The larger of the two figures is often the less actionable one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not produce a separate Mono build by habit.&lt;/strong&gt; On IL2CPP packages, Mono analysis is available through the SDK and Script Debugging configuration described above.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not enable every collection mode at once "to be safe."&lt;/strong&gt; Each mode adds instrumentation cost, and the combined overhead affects the run to different degrees. Enable Resource or Lua collection inside an Overview session only when you need data from subsystems that must be read together — for example, a texture's size and its Mono-side wrapper in one report — and follow the documented caveats about the performance impact of combined modes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Practical Recommendations
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;What to inspect&lt;/th&gt;
&lt;th&gt;How to judge&lt;/th&gt;
&lt;th&gt;What to change&lt;/th&gt;
&lt;th&gt;What to expect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Build configuration&lt;/td&gt;
&lt;td&gt;Mono data present or absent&lt;/td&gt;
&lt;td&gt;Enable Script Debugging, SDK 2.4.5+&lt;/td&gt;
&lt;td&gt;Data becomes available without a Mono build&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Reserved vs Used&lt;/td&gt;
&lt;td&gt;Which figure is driving the total&lt;/td&gt;
&lt;td&gt;Nothing yet&lt;/td&gt;
&lt;td&gt;A clear statement of capacity vs retention&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Used over time&lt;/td&gt;
&lt;td&gt;Monotonic growth across sampling points&lt;/td&gt;
&lt;td&gt;Retained reference chain, including Lua&lt;/td&gt;
&lt;td&gt;Flattened Used curve after the fix&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Stutter frame categories&lt;/td&gt;
&lt;td&gt;Share of frames attributed to GC&lt;/td&gt;
&lt;td&gt;Allocation rate per frame&lt;/td&gt;
&lt;td&gt;Fewer collection-triggered spikes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Collection call sites&lt;/td&gt;
&lt;td&gt;Duration and frequency of &lt;code&gt;GC.Collect&lt;/code&gt; / &lt;code&gt;UnloadUnused&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Call timing in your code&lt;/td&gt;
&lt;td&gt;Predictable, bounded collection cost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Scene-load functions&lt;/td&gt;
&lt;td&gt;Load-time stutter categories&lt;/td&gt;
&lt;td&gt;Loading path, not gameplay allocation&lt;/td&gt;
&lt;td&gt;Load spikes addressed at their actual source&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A large Mono heap is a measurement question before it is an optimization question.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mono Reserved&lt;/strong&gt; shows capacity; &lt;strong&gt;Mono Used&lt;/strong&gt; shows retention. Growth in Used is the leak signal.&lt;/li&gt;
&lt;li&gt;GC stutter comes from allocation frequency, not from heap size alone.&lt;/li&gt;
&lt;li&gt;Lua references to Mono objects can retain managed memory invisibly to C#-side review.&lt;/li&gt;
&lt;li&gt;GameOptim suggests keeping the heap within roughly 80 MB and running a Mono-mode test above that — a trigger for investigation, not a failure threshold.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does a large Mono heap always mean a memory leak?&lt;/strong&gt;&lt;br&gt;
No. A heap can be large because a large live set is legitimately retained, or because the runtime reserved capacity it has not yet needed. A leak requires Used memory to keep growing across a session without being released.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is 80 MB a hard limit for a Unity Mono heap?&lt;/strong&gt;&lt;br&gt;
It is GameOptim's suggested ceiling, and the point at which a deeper Mono-mode test is recommended. The real limit depends on your target device's total memory budget and what else the game needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why can't I see Mono data in my IL2CPP build?&lt;/strong&gt;&lt;br&gt;
Check the SDK version and the build option: Mono heap collection on IL2CPP requires SDK 2.4.5 or later with Script Debugging enabled. This is a configuration prerequisite, not a runtime behavior to debug.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How can Lua cause a Mono memory leak?&lt;/strong&gt;&lt;br&gt;
When Lua holds a reference to a Mono object, the managed object stays reachable and cannot be collected. Mono object reference data in the report exposes these links, which is why Lua memory and Mono memory are worth reading together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should I enable Mono, Resource, and Lua collection in the same run?&lt;/strong&gt;&lt;br&gt;
Only when you need those subsystems correlated in one report — for example, resource lifetime next to the managed object that owns it. Each enabled mode adds instrumentation cost, so combined runs should be judged against the documented impact rather than assumed to be free.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>resources</category>
      <category>memory</category>
    </item>
    <item>
      <title>How Can You Diagnose Lua Memory Issues in Unity Games?</title>
      <dc:creator>GameOptim</dc:creator>
      <pubDate>Mon, 26 Oct 2026 07:56:17 +0000</pubDate>
      <link>https://dev.to/gameoptim/how-can-you-diagnose-lua-memory-issues-in-unity-games-1ee5</link>
      <guid>https://dev.to/gameoptim/how-can-you-diagnose-lua-memory-issues-in-unity-games-1ee5</guid>
      <description>&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Overall Lua heap memory helps track memory usage and the counts of important Lua object types, including tables, userdata, and functions.&lt;/li&gt;
&lt;li&gt;Heap allocation call stacks help identify Lua functions responsible for substantial allocations and guide targeted optimization.&lt;/li&gt;
&lt;li&gt;Reverse call-stack analysis makes it easier to trace allocations to the Lua function and source location responsible for them.&lt;/li&gt;
&lt;li&gt;Cached C# object references can help explain why objects remain referenced and cannot be released as expected.&lt;/li&gt;
&lt;li&gt;Lua source files provide more useful function-location information than bytecode for this analysis, because the reported ending line number is always &lt;code&gt;0&lt;/code&gt; when Lua scripts run as bytecode.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Are the Main Lua Memory Problems in Unity?
&lt;/h2&gt;

&lt;p&gt;Lua is commonly used to support hot updates, allowing development teams to add features and fix bugs without rebuilding the entire game. However, as Lua usage grows, memory allocation and object lifetime management can introduce runtime performance problems.&lt;/p&gt;

&lt;p&gt;Two issues deserve particular attention:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Excessive memory allocation: Lua functions allocate substantial amounts of heap memory, potentially increasing garbage collection (GC) frequency and the cost of GC operations.&lt;/li&gt;
&lt;li&gt;Unreleased references: Lua-related references to C# objects remain in a cache, preventing those objects from being released as expected and potentially contributing to C# memory leaks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These problems require different investigations. Allocation analysis helps identify where memory is being created, while reference analysis helps identify objects that remain referenced over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can You Analyze Overall Lua Heap Memory?
&lt;/h2&gt;

&lt;p&gt;The overall heap memory report tracks Lua's total memory usage over time, along with the counts of three important Lua object types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Table&lt;/li&gt;
&lt;li&gt;Userdata&lt;/li&gt;
&lt;li&gt;Function&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By examining these metrics at different frames, developers can determine how Lua memory usage evolves during gameplay.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Should You Look for in the Memory Trend?
&lt;/h3&gt;

&lt;p&gt;Start by examining Lua's total heap memory across the captured session.&lt;/p&gt;

&lt;p&gt;Ask the following questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does Lua memory remain within the expected range during the tested gameplay?&lt;/li&gt;
&lt;li&gt;Does memory usage continue to increase as the game runs?&lt;/li&gt;
&lt;li&gt;Do changes in total memory coincide with changes in the number of tables, userdata objects, or functions?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The purpose is to establish whether the observed memory usage matches expectations and whether the trend warrants further investigation.&lt;/p&gt;

&lt;p&gt;An increasing memory trend is a reason to investigate, not sufficient proof of a memory leak. Use the overall report to identify suspicious periods, then inspect detailed allocations or object references to understand what is happening.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can You Find the Lua Functions Allocating the Most Memory?
&lt;/h2&gt;

&lt;p&gt;The overall heap report shows the memory trend, but it does not by itself identify the functions responsible for allocations.&lt;/p&gt;

&lt;p&gt;The detailed heap allocation report addresses this problem by allowing developers to inspect allocation call stacks for a specific frame.&lt;/p&gt;

&lt;p&gt;This helps answer two practical questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which Lua functions are responsible for substantial heap allocations?&lt;/li&gt;
&lt;li&gt;Which lines of Lua code should be investigated for optimization?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1: Select a Frame and Inspect Allocation Call Stacks
&lt;/h3&gt;

&lt;p&gt;Choose a frame of interest and examine the allocation call stacks recorded for that frame.&lt;/p&gt;

&lt;p&gt;Focus on functions associated with substantial allocations. Their call stacks provide the context needed to trace allocations through the Lua code.&lt;/p&gt;

&lt;p&gt;This approach helps narrow the investigation from a game-wide memory problem to specific functions that may be worth optimizing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Use Reverse Call-Stack Analysis to Locate the Source
&lt;/h3&gt;

&lt;p&gt;The report also supports a reverse call-stack viewing mode, similar to the reverse analysis available for Mono heap memory.&lt;/p&gt;

&lt;p&gt;Switching the viewing mode makes it easier to identify the deeper Lua functions responsible for allocations, rather than having to work through the original call-stack order.&lt;/p&gt;

&lt;p&gt;The goal is to locate the specific Lua script and source line associated with substantial heap allocation. Developers can then inspect the corresponding code and determine whether the allocation behavior can be improved.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Does Lua Function Naming Matter?
&lt;/h3&gt;

&lt;p&gt;Lua functions are represented using the following naming format:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;X@Y:Z&lt;/code&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;X&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Function name. If the name cannot be obtained, it is shown as &lt;code&gt;unknown&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Y&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Location of the file where the function is defined.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Z&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ending line number of the function definition.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;There is an important limitation: when Lua scripts run as bytecode, the reported ending line number is always &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For this reason, developers should use Lua source files during testing whenever possible. Source-based testing provides more useful location information when tracing allocations back to the code that produced them.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can Lua References Cause C# Memory Leaks?
&lt;/h2&gt;

&lt;p&gt;Lua memory analysis is not limited to allocations within the Lua heap. References between Lua and C# can also affect object lifetimes in Unity projects.&lt;/p&gt;

&lt;p&gt;Lua plugins commonly maintain a cache on the C# side for objects accessed by Lua. This cache helps prevent a C# object from being garbage-collected while Lua still needs to access it.&lt;/p&gt;

&lt;p&gt;Without an appropriate reference-management mechanism, a C# object could be collected before Lua attempts to access it again, potentially causing logic errors.&lt;/p&gt;

&lt;p&gt;However, a cached reference can also prevent an object from being released when it is no longer needed. If unnecessary references accumulate, they can contribute to memory leaks on the C# side.&lt;/p&gt;

&lt;p&gt;This is why investigating Lua-related memory issues sometimes requires examining Mono objects rather than looking only at Lua heap usage.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Does the Mono Object Reference Report Help?
&lt;/h3&gt;

&lt;p&gt;The Mono object reference report summarizes C# objects held in the relevant caches maintained by Lua plugins.&lt;/p&gt;

&lt;p&gt;It provides two useful types of information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Object types and counts: the types of C# objects present in the cache and the total number of objects for each type.&lt;/li&gt;
&lt;li&gt;Destroyed Unity objects: for types inheriting from &lt;code&gt;UnityEngine.Object&lt;/code&gt;, the report also counts objects that have already been destroyed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The second metric is particularly useful when investigating references to Unity objects that have been destroyed but may still appear in the cache.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Can You Identify Suspicious Object References?
&lt;/h3&gt;

&lt;p&gt;Follow this investigation sequence:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the Mono object reference report and review the object types and their counts.&lt;/li&gt;
&lt;li&gt;Identify object types whose counts continue to increase across sampling points.&lt;/li&gt;
&lt;li&gt;Compare the references at two different sampling points for a suspicious object type.&lt;/li&gt;
&lt;li&gt;Use the differences to investigate which Lua references may be unnecessary or improperly retained.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The report helps narrow the investigation to specific object types and changes in their reference counts. Developers can then inspect the relevant Lua code and reference-management logic.&lt;/p&gt;

&lt;p&gt;A growing cache count does not automatically establish that every retained object is leaked. The key is to determine whether those references are still required by the game's logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Should You Check First When Investigating Lua Memory Issues?
&lt;/h2&gt;

&lt;p&gt;The most efficient starting point depends on the symptom you observe.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Observed symptom&lt;/th&gt;
&lt;th&gt;What to inspect first&lt;/th&gt;
&lt;th&gt;Next step&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lua heap memory is unexpectedly high&lt;/td&gt;
&lt;td&gt;Overall heap memory trend and Lua object counts&lt;/td&gt;
&lt;td&gt;Identify suspicious periods and inspect detailed allocations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lua heap allocations are substantial&lt;/td&gt;
&lt;td&gt;Per-frame allocation call stacks&lt;/td&gt;
&lt;td&gt;Use reverse call-stack analysis to locate the relevant Lua functions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C# object counts continue to increase&lt;/td&gt;
&lt;td&gt;Mono object reference report&lt;/td&gt;
&lt;td&gt;Compare object references at different sampling points&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Destroyed Unity objects remain in the cache&lt;/td&gt;
&lt;td&gt;Destroyed-object counts for types inheriting from &lt;code&gt;UnityEngine.Object&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Investigate whether Lua-related references are still being retained&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Allocation locations are difficult to identify&lt;/td&gt;
&lt;td&gt;Lua function names and source-location information&lt;/td&gt;
&lt;td&gt;Prefer source-based Lua testing over bytecode when possible&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This sequence separates three distinct questions: how much memory Lua uses, where Lua allocates memory, and which C# objects remain referenced.&lt;/p&gt;

&lt;p&gt;Investigating the appropriate report first helps avoid optimizing unrelated code or assuming that every memory increase has the same cause.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which Lua Memory Analysis Tools Are Supported?
&lt;/h2&gt;

&lt;p&gt;GameOptim GOT Online's Lua memory analysis supports several widely used Lua plugins:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;uLua&lt;/li&gt;
&lt;li&gt;ToLua&lt;/li&gt;
&lt;li&gt;SLua&lt;/li&gt;
&lt;li&gt;xLua&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a development team recompiles the Lua native library under a custom name, the library name can be specified through the &lt;code&gt;UWAEngine.SetOverrideLuaLib&lt;/code&gt; interface.&lt;/p&gt;

&lt;p&gt;This configuration is relevant when the project's Lua native library does not use one of the expected library names. Correctly identifying the library helps the analysis support the project's Lua integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Track trends before diagnosing leaks. Overall Lua heap memory and object counts help identify suspicious changes during gameplay.&lt;/li&gt;
&lt;li&gt;Trace allocations to their source. Per-frame allocation call stacks and reverse stack viewing help locate Lua functions and source lines responsible for substantial allocations.&lt;/li&gt;
&lt;li&gt;Use Lua source files during testing when possible. Bytecode execution causes the reported function-ending line number to remain &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Investigate references as well as allocations. Lua plugin caches can retain C# objects and contribute to memory leaks if references are no longer needed.&lt;/li&gt;
&lt;li&gt;Compare multiple sampling points. Changes in cached object counts and references help narrow down suspicious object lifetimes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Does increasing Lua heap memory always indicate a memory leak?
&lt;/h3&gt;

&lt;p&gt;No. An increase in Lua heap memory is a signal to investigate, but it does not prove that a memory leak exists. Check the memory trend, object counts, and detailed allocation data before drawing a conclusion.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. How can I find the Lua function responsible for excessive allocations?
&lt;/h3&gt;

&lt;p&gt;Use the detailed heap allocation report to inspect allocation call stacks for a specific frame. Reverse call-stack viewing can help trace substantial allocations to the relevant Lua function and source location.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Why does the Lua function's ending line number show &lt;code&gt;0&lt;/code&gt;?
&lt;/h3&gt;

&lt;p&gt;When Lua scripts run as bytecode, the reported ending line number is always &lt;code&gt;0&lt;/code&gt;. For more useful source-location information during allocation analysis, use Lua source files in testing whenever possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Why can Lua cause memory leaks in C# objects?
&lt;/h3&gt;

&lt;p&gt;Lua plugins commonly maintain C#-side caches to keep objects referenced by Lua from being collected prematurely. If objects remain in these caches after the references are no longer needed, they may not be released as expected, contributing to C# memory leaks.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. How can I investigate destroyed Unity objects that remain referenced?
&lt;/h3&gt;

&lt;p&gt;Use the Mono object reference report to inspect destroyed-object counts for cached types that inherit from &lt;code&gt;UnityEngine.Object&lt;/code&gt;. Compare references across sampling points and investigate whether Lua-related references are being retained unnecessarily.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>lua</category>
      <category>gamedev</category>
      <category>performance</category>
    </item>
    <item>
      <title>How Can Unity Developers Identify Asset Loading Bottlenecks with GOT Online?</title>
      <dc:creator>GameOptim</dc:creator>
      <pubDate>Tue, 20 Oct 2026 08:42:15 +0000</pubDate>
      <link>https://dev.to/gameoptim/how-can-unity-developers-identify-asset-loading-bottlenecks-with-got-online-62b</link>
      <guid>https://dev.to/gameoptim/how-can-unity-developers-identify-asset-loading-bottlenecks-with-got-online-62b</guid>
      <description>&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Asset loading delays and excessive resource operations can cause noticeable stuttering in Unity games. To help developers identify the underlying causes, GameOptim's GOT Online Overview mode introduces Resource Management, which provides quantitative analysis of resource loading and unloading, as well as GameObject instantiation and activation. Developers can inspect execution time, call frequency, AssetBundle information, and the APIs used for resource operations.&lt;/p&gt;

&lt;p&gt;GOT Online also adds scene segmentation, allowing developers to analyze performance costs within specific scenes, UI screens, or other sections of gameplay. These features help development teams narrow down loading bottlenecks and conduct more targeted performance investigations.&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;As a Unity project grows in complexity and the number of assets increases, resource loading can become a significant performance concern. However, identifying which resource, AssetBundle, or loading operation is responsible for excessive execution time is not always straightforward.&lt;/p&gt;

&lt;p&gt;GameOptim has enhanced GOT Online's Overview mode with resource management analysis and scene segmentation. These features allow developers to examine resource operations quantitatively and break down performance data into more specific sections, making it easier to investigate loading bottlenecks and understand where execution time is being spent.&lt;/p&gt;

&lt;h1&gt;
  
  
  Main Body
&lt;/h1&gt;

&lt;h2&gt;
  
  
  How Can You Identify Asset Loading Bottlenecks in Unity?
&lt;/h2&gt;

&lt;p&gt;Resource loading is an important area to investigate when diagnosing performance issues. As a project becomes more complex and contains more assets, loading operations can become more noticeable sources of stuttering.&lt;/p&gt;

&lt;p&gt;The key question is: Which resources, AssetBundles, or loading operations are consuming the most time?&lt;/p&gt;

&lt;p&gt;Previously, GameOptim shared techniques for investigating this problem in a &lt;a href="https://www.gameoptim.com/blog/post/LoadingResource" rel="noopener noreferrer"&gt;technical article about resource loading&lt;/a&gt;. With the new Resource Management feature in GOT Online's Overview mode, developers can now quantify the execution costs of individual resource operations directly in the online report.&lt;/p&gt;

&lt;p&gt;The analysis covers operations such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Resource loading and unloading.&lt;/li&gt;
&lt;li&gt;GameObject instantiation and activation.&lt;/li&gt;
&lt;li&gt;Execution time and operation frequency.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This detailed breakdown helps developers identify the specific operations that deserve further investigation instead of relying solely on overall loading performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which Resources Should You Investigate First?
&lt;/h2&gt;

&lt;p&gt;The Resource Management overview highlights the top 10 resources with the highest loading costs and the top 10 with the highest operation frequencies that warrant attention.&lt;/p&gt;

&lt;p&gt;By surfacing these high-priority resources, GOT Online helps developers focus their investigation on operations with significant execution costs or frequent calls.&lt;/p&gt;

&lt;p&gt;Reviewing these resources first can help teams prioritize their optimization efforts and identify opportunities for improvements without having to inspect every resource individually.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can You Analyze AssetBundle Loading and Resource APIs?
&lt;/h2&gt;

&lt;p&gt;In addition to the overall resource statistics, GOT Online provides a dedicated Resource Loading/Unloading page for examining individual loading operations.&lt;/p&gt;

&lt;p&gt;For each relevant operation, developers can inspect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AssetBundle: Which AssetBundle contains the loaded resource.&lt;/li&gt;
&lt;li&gt;API used: Which interface was used to load the resource.&lt;/li&gt;
&lt;li&gt;Execution time: How long the loading operation took.&lt;/li&gt;
&lt;li&gt;Call count: How many times the operation occurred.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This information helps developers investigate both the resources involved and the methods used to load them. For example, when a resource appears among the high-cost or high-frequency operations, developers can examine its AssetBundle, loading API, execution time, and call count to better understand the source of the cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can Scene Segmentation Improve Performance Analysis?
&lt;/h2&gt;

&lt;p&gt;Performance data aggregated across an entire gameplay session may not provide enough detail to determine which scene or UI section is responsible for a particular cost.&lt;/p&gt;

&lt;p&gt;GOT Online introduces scene segmentation, allowing developers to divide captured performance data into more specific sections. This makes it possible to analyze execution costs for different scenes, UI screens, and other parts of a gameplay flow separately.&lt;/p&gt;

&lt;p&gt;To configure scene segmentation, open Scene Overview → Scene Management and click Add Scene Marker. Enter the segmentation position and scene name to define the new section. GOT Online can then present the corresponding performance analysis based on the updated segmentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Does Performance Analysis Look Like Before Scene Segmentation?
&lt;/h3&gt;

&lt;p&gt;Before segmentation, performance data is presented without the newly defined section boundaries, making it harder to isolate costs associated with a particular part of the gameplay flow.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Does Scene Segmentation Change the Analysis?
&lt;/h3&gt;

&lt;p&gt;After segmentation, developers can examine the data within the newly defined sections, making it easier to distinguish performance costs associated with different scenes or UI sections.&lt;/p&gt;

&lt;p&gt;By dividing performance data into meaningful sections, teams can conduct more focused investigations and better understand how execution costs vary across different parts of the game.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is GOT Online, and Which Performance Analysis Modes Does It Support?
&lt;/h2&gt;

&lt;p&gt;GameOptim GOT Online is a lightweight performance analysis service built on its local testing workflow. Development teams can quickly synchronize locally collected performance data to the GameOptim website and generate online analysis reports.&lt;/p&gt;

&lt;p&gt;GOT Online combines local testing with online report access, allowing teams to review performance data through a centralized reporting workflow.&lt;/p&gt;

&lt;p&gt;The service currently provides four performance analysis modes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Overview: Overall performance analysis.&lt;/li&gt;
&lt;li&gt;Mono: Mono heap memory analysis.&lt;/li&gt;
&lt;li&gt;Lua: Lua performance analysis.&lt;/li&gt;
&lt;li&gt;GPU: GPU performance analysis.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These modes support different aspects of game performance investigation, from overall execution costs and resource loading to memory usage, Lua behavior, and GPU performance.&lt;/p&gt;

&lt;h1&gt;
  
  
  What Should Unity Developers Take Away?
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Prioritize high-cost resource operations: Use Resource Management in Overview mode to identify resources with high loading costs or operation frequencies.&lt;/li&gt;
&lt;li&gt;Inspect individual loading operations: Check AssetBundle information, the APIs used, execution time, and call count to investigate loading bottlenecks.&lt;/li&gt;
&lt;li&gt;Analyze GameObject operations: Examine the time spent instantiating and activating GameObjects alongside resource loading and unloading.&lt;/li&gt;
&lt;li&gt;Use scene segmentation for finer analysis: Divide performance data into specific scenes or UI sections to isolate execution costs.&lt;/li&gt;
&lt;li&gt;Choose the appropriate analysis mode: Use Overview for overall performance, Mono for heap memory, Lua for Lua performance, and GPU for GPU performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  FAQ
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Q1. How can Unity developers identify which assets cause loading bottlenecks?
&lt;/h3&gt;

&lt;p&gt;Use Resource Management in GOT Online's Overview mode to examine resource loading costs and operation frequencies. The overview highlights the top 10 resources in each category, helping developers prioritize their investigation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q2. What information does GOT Online provide for resource loading operations?
&lt;/h3&gt;

&lt;p&gt;The Resource Loading/Unloading page shows which AssetBundle contains a resource, which API was used, how much time the operation took, and how many times it occurred.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q3. Can GOT Online analyze GameObject instantiation and activation costs?
&lt;/h3&gt;

&lt;p&gt;Yes. Resource Management provides quantitative analysis of GameObject instantiation and activation, alongside resource loading and unloading operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q4. What is scene segmentation in GOT Online?
&lt;/h3&gt;

&lt;p&gt;Scene segmentation allows developers to divide performance data into specific sections, such as individual scenes or UI screens, so they can analyze execution costs more precisely.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q5. How do you configure scene segmentation in GOT Online?
&lt;/h3&gt;

&lt;p&gt;Navigate to Scene Overview → Scene Management, click Add Scene Marker, and enter the segmentation position and scene name. The report can then display performance data according to the defined sections.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q6. Which performance analysis modes does GOT Online support?
&lt;/h3&gt;

&lt;p&gt;GOT Online provides four modes: Overview for overall performance analysis, Mono for Mono heap memory analysis, Lua for Lua performance analysis, and GPU for GPU performance analysis.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>performance</category>
      <category>profiling</category>
    </item>
    <item>
      <title>How Can Unity Developers Identify GC Stutters, Lua Leaks, and Mono Memory Issues with GOT Online?</title>
      <dc:creator>GameOptim</dc:creator>
      <pubDate>Fri, 16 Oct 2026 06:26:13 +0000</pubDate>
      <link>https://dev.to/gameoptim/how-can-unity-developers-identify-gc-stutters-lua-leaks-and-mono-memory-issues-with-got-online-2m7e</link>
      <guid>https://dev.to/gameoptim/how-can-unity-developers-identify-gc-stutters-lua-leaks-and-mono-memory-issues-with-got-online-2m7e</guid>
      <description>&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Investigating game performance issues often requires developers to connect CPU execution costs, garbage collection (GC) activity, Lua function calls, and Mono heap memory usage. GameOptim's GOT Online provides analysis capabilities across Overview, Lua, and Mono modes to help development teams identify performance bottlenecks and investigate memory-related problems.&lt;/p&gt;

&lt;p&gt;This article introduces several improvements to these modes, including GC call-frequency monitoring, CPU call-stack visualization, reverse Lua call-stack analysis, Lua leak investigation caused by Mono references, and more detailed Mono heap allocation and object-reference analysis. These features help developers move from observing performance symptoms to examining the functions, objects, and memory changes behind them.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can You Detect Frequent GC Calls in Unity?
&lt;/h2&gt;

&lt;p&gt;Garbage collection (GC) activity is one of the important indicators to examine when investigating game stuttering. To help developers monitor GC call frequency, GOT Online has added GC statistics to the loading module in Overview mode.&lt;/p&gt;

&lt;p&gt;GC call frequency is influenced by heap memory allocation. When functions allocate more heap memory, or allocate it more frequently, GC can be triggered sooner.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;GC.Collect&lt;/code&gt; is called frequently, as illustrated in the image above, developers should investigate the allocation behavior of the functions involved. This is particularly important when GC calls become increasingly frequent as the game runs longer.&lt;/p&gt;

&lt;p&gt;In such cases, developers can use GameOptim GOT Online's Mono mode to investigate whether Mono memory is being allocated too quickly or in excessive quantities. This helps connect observed GC activity with potential heap allocation issues that warrant further analysis.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can You Identify CPU Performance Hotspots More Quickly?
&lt;/h2&gt;

&lt;p&gt;GOT Online has improved the CPU call-stack analysis page to make it easier to understand execution-time trends and identify functions that contribute to CPU workload.&lt;/p&gt;

&lt;p&gt;The CPU execution-time chart displays the overall execution-time trend alongside the trends for top functions. By comparing these curves, developers can quickly identify which functions may be contributing to execution-time peaks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkn0bzloh9gt7xrdo75ms.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkn0bzloh9gt7xrdo75ms.png" alt="CPU execution-time trends and top functions in GOT Online" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This visualization makes it easier to examine changes in CPU execution time and investigate which functions are associated with unusually high values.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F663jabch52m7t2a6r5ci.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F663jabch52m7t2a6r5ci.png" alt="Detailed CPU function execution-time analysis in GOT Online" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The updated page also supports scene-specific analysis. Developers can navigate to a particular scene and examine the execution-time distribution of individual functions within that scene.&lt;/p&gt;

&lt;p&gt;This makes it easier to narrow the investigation to the relevant scene instead of relying only on aggregated CPU performance data.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can Reverse Call-Stack Analysis Help Identify Lua Performance Issues?
&lt;/h2&gt;

&lt;p&gt;Reverse analysis is one of the useful features in GOT Online's Lua mode because it helps developers trace memory allocation back through function relationships without repeatedly expanding deep call stacks.&lt;/p&gt;

&lt;p&gt;In reverse-analysis mode, expanding a node displays a list of direct parent functions that call the function represented by that node and generate heap allocations. By following these relationships, developers can trace the allocation back toward the functions responsible for it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F26msaw2uogpphev3vb9e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F26msaw2uogpphev3vb9e.png" alt="Reverse call-stack analysis in GOT Online Lua mode" width="800" height="505"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This approach reduces the need to navigate deeply nested call stacks one level at a time and helps developers narrow down the underlying allocation source more directly.&lt;/p&gt;

&lt;p&gt;The latest version also adds self-time percentage to the stack information for a selected frame. This metric helps developers identify functions that account for a larger proportion of the execution time within the analyzed stack.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxkk9czo7byu8c5bslbzd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxkk9czo7byu8c5bslbzd.png" alt="Self-time percentage in Lua frame stack information" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By examining self-time percentage alongside the existing stack information, developers can more easily identify functions that deserve closer investigation when analyzing performance costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can You Investigate Lua Memory Leaks Caused by Mono References?
&lt;/h2&gt;

&lt;p&gt;Lua memory leaks caused by Mono references are another important area of investigation in GOT Online's Lua mode.&lt;/p&gt;

&lt;p&gt;In the latest version, GOT Online improves how Mono objects are presented during leak analysis. Developers can inspect detailed information about Mono objects on a single page, including the number of destroyed objects and how that number changes over time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu5rplig5gkj54dw2r54y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu5rplig5gkj54dw2r54y.png" alt="Mono object details for Lua leak analysis in GOT Online" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The comparison mode also allows developers to compare different sampling points and examine whether the observed memory changes are reasonable.&lt;/p&gt;

&lt;p&gt;By reviewing object details, destruction counts, and changes between samples, developers can investigate potential Lua leaks associated with Mono references and determine which changes require further analysis.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can You Understand Where Mono Heap Memory Is Being Used?
&lt;/h2&gt;

&lt;p&gt;High Mono memory usage can be difficult to investigate because memory problems can arise in different ways. Developers need to understand not only how much memory is occupied, but also where that memory is being used.&lt;/p&gt;

&lt;p&gt;GOT Online's latest Mono mode improves the presentation of heap memory leak analysis, making it easier to investigate why Mono memory usage is high and how the memory is distributed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fol98dkyxdy0gusb7tn3x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fol98dkyxdy0gusb7tn3x.png" alt="Mono heap memory usage and leak analysis in GOT Online" width="799" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The visualization provides an overview of Mono memory usage, helping developers examine the memory distribution and identify areas that warrant closer investigation.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can You Trace Mono Heap Memory Back to Specific Functions and Variables?
&lt;/h2&gt;

&lt;p&gt;GOT Online provides additional details at both the function and memory-sample levels to help developers investigate Mono memory usage.&lt;/p&gt;

&lt;p&gt;The function view displays the actual heap memory usage associated with each function during game execution. This helps developers examine which functions are associated with memory consumption.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9zpxas1mdlwe4z6am7az.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9zpxas1mdlwe4z6am7az.png" alt="Function-level Mono heap memory usage in GOT Online" width="799" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Developers can also select any bar in the chart below to inspect details about actual heap memory usage and the variables residing in memory at that sample.&lt;/p&gt;

&lt;p&gt;Within the Mono object reference view, developers can select any two memory samples from the bar chart and compare their memory changes. This comparison helps them identify specific functions associated with memory growth and investigate the corresponding memory increments and variables.&lt;/p&gt;

&lt;p&gt;By tracing changes across sampling points, developers can narrow down potential sources of memory leaks and gather more specific information for further debugging and remediation.&lt;/p&gt;

&lt;h1&gt;
  
  
  What Should Unity Developers Take Away?
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Monitor GC call frequency: Use GC statistics in Overview mode to investigate frequent &lt;code&gt;GC.Collect&lt;/code&gt; calls and potential excessive heap allocation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use CPU execution-time trends: Compare overall CPU costs with top-function trends and inspect specific scenes to narrow down performance hotspots.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Trace Lua allocations through reverse analysis: Follow parent-function relationships to investigate allocation sources, and use self-time percentage to identify functions with higher execution costs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compare Mono object samples: Examine object details, destruction counts, and changes between sampling points when investigating Lua leaks caused by Mono references.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Trace Mono memory to functions and variables: Use function-level heap memory data and comparisons between memory samples to investigate memory growth and potential leak sources.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  FAQ
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Q1. How can developers investigate frequent GC calls in Unity?
&lt;/h3&gt;

&lt;p&gt;Developers can use the GC statistics in GOT Online's Overview mode to examine GC call frequency. If calls become increasingly frequent during gameplay, they can use Mono mode to investigate whether heap memory allocation is occurring too quickly or in excessive quantities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q2. How does GOT Online help identify CPU performance hotspots?
&lt;/h3&gt;

&lt;p&gt;Overview mode displays overall CPU execution-time trends alongside trends for top functions. Developers can examine execution-time peaks, investigate the functions associated with those peaks, and use scene-specific analysis to inspect function execution-time distributions within individual scenes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q3. What is reverse analysis in GOT Online's Lua mode?
&lt;/h3&gt;

&lt;p&gt;Reverse analysis displays direct parent functions that call a selected function and generate heap allocations. Developers can follow these function relationships to trace allocations toward their sources without repeatedly navigating deeply nested call stacks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q4. How can developers investigate Lua leaks caused by Mono references?
&lt;/h3&gt;

&lt;p&gt;Developers can inspect Mono object details, including destruction counts and their trends, in GOT Online's Lua leak analysis. They can also compare sampling points to investigate memory changes and determine whether the observed increments warrant further investigation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q5. How can GOT Online help investigate Mono memory leaks?
&lt;/h3&gt;

&lt;p&gt;Mono mode provides function-level heap memory usage, detailed information about memory usage at selected samples, and the variables residing in memory. Comparing two sampling points in the Mono object reference view helps developers investigate memory increments and identify functions and variables associated with potential leaks.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>performance</category>
      <category>memory</category>
    </item>
    <item>
      <title>How Can Unity Developers Identify and Analyze Stuttering Frames with GOT Online?</title>
      <dc:creator>GameOptim</dc:creator>
      <pubDate>Tue, 13 Oct 2026 09:19:34 +0000</pubDate>
      <link>https://dev.to/gameoptim/how-can-unity-developers-identify-and-analyze-stuttering-frames-with-got-online-5eon</link>
      <guid>https://dev.to/gameoptim/how-can-unity-developers-identify-and-analyze-stuttering-frames-with-got-online-5eon</guid>
      <description>&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Identifying the root cause of frame stuttering in Unity games can be time-consuming, especially when developers need to inspect performance data and function call stacks manually. GOT Online's Overview mode now includes a Stutter Analysis feature that automatically identifies stuttering frames and provides detailed function stack statistics for each identified point.&lt;/p&gt;

&lt;p&gt;This article explains how stuttering frames are identified in GOT Online, what function stack data is available, and how Unity developers can use this information to investigate performance issues more efficiently.&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Frame stuttering can negatively affect the gameplay experience, but identifying its root cause requires more than simply observing a drop in frame rate. Developers need to determine which frames experienced significant delays and investigate the function calls responsible for the additional execution time.&lt;/p&gt;

&lt;p&gt;To make this process more efficient, GameOptim has introduced Stutter Analysis in GOT Online's Overview mode, incorporating feedback from development teams. The feature identifies stuttering frames during gameplay and provides detailed function stack statistics to help developers investigate the underlying causes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Qualifies as a Stuttering Frame in GOT Online?
&lt;/h2&gt;

&lt;p&gt;GOT Online's Stutter Analysis feature identifies frames that meet both of the following conditions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The current frame time exceeds 83.33 ms.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The current frame time exceeds twice the average frame time of the previous three frames.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A frame must satisfy both conditions to be classified as a stuttering frame.&lt;/p&gt;

&lt;p&gt;By applying these criteria, GOT Online lists the identified stuttering frames in a dedicated Stutter Analysis section on the Overview report page. Developers can use this list to quickly locate frames that experienced significant delays during execution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://uploader.shimo.im/f/wYylBgfFa0ARVQzn.png" rel="noopener noreferrer"&gt;Image: Stutter Analysis section in the GOT Online Overview report&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Function Stack Data Is Available for Each Stuttering Point?
&lt;/h2&gt;

&lt;p&gt;Identifying a stuttering frame is only the first step. Developers also need to investigate which function calls contributed to the delay.&lt;/p&gt;

&lt;p&gt;GOT Online provides detailed function stack statistics for the relevant nodes associated with each stuttering point. The available information includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Execution time percentage: The proportion of time attributed to a function or node.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Execution time: The specific time consumed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Call count: The number of times the function was called.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These metrics help developers examine the execution costs associated with abnormal nodes and investigate the function stacks behind a stuttering frame.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://uploader.shimo.im/f/ZwrdQMQIX3y9kgyQ.png" rel="noopener noreferrer"&gt;Image: Function stack statistics for a stuttering point in GOT Online&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can Developers Use Stutter Analysis to Investigate Performance Issues?
&lt;/h2&gt;

&lt;p&gt;GOT Online allows developers to switch quickly between different stuttering points and inspect the corresponding function stacks.&lt;/p&gt;

&lt;p&gt;This workflow helps development teams move from identifying a frame-time anomaly to examining the detailed execution data associated with that specific point.&lt;/p&gt;

&lt;p&gt;Rather than investigating every frame manually, developers can focus on the identified stuttering frames, compare the relevant function stack information, and use execution time, time percentage, and call count to investigate potential causes.&lt;/p&gt;

&lt;p&gt;The function stack data provides a more detailed basis for determining which parts of execution warrant further investigation, helping developers locate the specific causes of stuttering more efficiently.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does Stutter Analysis Fit into the GOT Online Overview Workflow?
&lt;/h2&gt;

&lt;p&gt;Stutter Analysis is integrated directly into the Overview report in GOT Online. Developers can review the list of stuttering frames and inspect the corresponding function stack statistics within the same reporting workflow.&lt;/p&gt;

&lt;p&gt;This integration connects two important stages of performance investigation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Identify abnormal frames: Locate frames that meet the stuttering criteria.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inspect execution details: Examine function stack statistics at each stuttering point to investigate the cause.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By bringing these capabilities together, GOT Online helps streamline the process of moving from frame-time anomalies to detailed performance analysis.&lt;/p&gt;

&lt;h1&gt;
  
  
  What Should Unity Developers Take Away?
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Check both stuttering criteria: A frame must exceed 83.33 ms and twice the average frame time of the previous three frames.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start with the identified frames: Use the Stutter Analysis section in the GOT Online Overview report to locate stuttering points.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inspect function stack statistics: Examine execution time percentage, execution time, and call count for relevant nodes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compare different stuttering points: Switch between identified frames to investigate their corresponding function stacks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use detailed execution data to guide investigation: Move beyond identifying frame-time anomalies and investigate the specific causes through function stack analysis.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  FAQ
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Q1. What is considered a stuttering frame in GOT Online?
&lt;/h3&gt;

&lt;p&gt;A frame is classified as a stuttering frame when its frame time exceeds 83.33 ms and is more than twice the average frame time of the previous three frames. Both conditions must be met.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q2. Where can I find stuttering frames in GOT Online?
&lt;/h3&gt;

&lt;p&gt;Stuttering frames are listed in the Stutter Analysis section of the Overview report in the latest version that includes this feature.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q3. What information does GOT Online provide for each stuttering point?
&lt;/h3&gt;

&lt;p&gt;GOT Online provides detailed function stack statistics, including execution time percentage, specific execution time, and call count, helping developers investigate the execution costs associated with abnormal nodes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q4. How can developers investigate the causes of stuttering?
&lt;/h3&gt;

&lt;p&gt;Developers can switch between different stuttering points and inspect their corresponding function stacks. By examining execution time, time percentage, and call count, they can investigate which function calls may be contributing to the observed delays.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q5. Is Stutter Analysis available in GOT Online's Overview mode?
&lt;/h3&gt;

&lt;p&gt;Yes. GameOptim has introduced Stutter Analysis in GOT Online's Overview mode, adding a dedicated section for identified stuttering frames and their associated function stack statistics.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>performance</category>
      <category>stutter</category>
    </item>
    <item>
      <title>How Can Unity Developers Track Managed Heap Allocations on Worker Threads?</title>
      <dc:creator>GameOptim</dc:creator>
      <pubDate>Fri, 09 Oct 2026 03:21:28 +0000</pubDate>
      <link>https://dev.to/gameoptim/how-can-unity-developers-track-managed-heap-allocations-on-worker-threads-2d4e</link>
      <guid>https://dev.to/gameoptim/how-can-unity-developers-track-managed-heap-allocations-on-worker-threads-2d4e</guid>
      <description>&lt;p&gt;Moving work that does not require Unity APIs to worker threads can reduce main-thread pressure and help improve frame rates. However, identifying managed heap allocations on these threads can be challenging because Unity Profiler may not show their &lt;code&gt;GC.Alloc&lt;/code&gt; activity.&lt;/p&gt;

&lt;p&gt;GOT Online's Mono mode now supports &lt;strong&gt;multithreaded allocation statistics&lt;/strong&gt;, allowing developers to inspect managed heap allocations made by non-main threads, investigate potential memory leaks, and compare heap growth between snapshots.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.gameoptim.com/?fopt=dev" rel="noopener noreferrer"&gt;New users can get 2 hours of free GOT Online testing time after completing registration.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;To reduce main-thread workload and improve frame rates, Unity developers often move operations that do not depend on Unity APIs to worker threads.&lt;/p&gt;

&lt;p&gt;However, when analyzing managed heap usage, it can be difficult to identify exactly where allocations occur on these threads. This makes memory profiling and leak investigation more challenging.&lt;/p&gt;

&lt;p&gt;To address this issue, GOT Online supports multithreaded statistics in &lt;strong&gt;Mono mode&lt;/strong&gt;. Combined with GOT Online's flexible workflow for testing changes and checking results, this feature helps developers investigate memory allocation issues more efficiently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Should Unity Developers Track Heap Allocations on Worker Threads?
&lt;/h2&gt;

&lt;p&gt;Consider a component that starts two worker threads in &lt;code&gt;Start()&lt;/code&gt;. Both threads periodically allocate managed heap memory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdgtut3ow59ua31mzdrle.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdgtut3ow59ua31mzdrle.png" alt=" " width="800" height="1092"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this scenario, Unity Profiler may not display the &lt;code&gt;GC.Alloc&lt;/code&gt; activity associated with these worker-thread allocations.&lt;/p&gt;

&lt;p&gt;However, these allocations still matter. Like allocations on the main thread, they can contribute to garbage collection overhead when allocations occur frequently. If objects remain referenced longer than intended, they can also contribute to sustained heap growth or memory leaks.&lt;/p&gt;

&lt;p&gt;Being able to identify where these allocations originate is therefore important when investigating managed memory usage in multithreaded Unity projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can GOT Online Identify Managed Allocations on Worker Threads?
&lt;/h2&gt;

&lt;p&gt;Run a test using &lt;strong&gt;Mono mode&lt;/strong&gt; in GOT Online, then open the &lt;strong&gt;Detailed Heap Allocations&lt;/strong&gt; page in the performance report.&lt;/p&gt;

&lt;p&gt;Functions associated with allocations on non-main threads appear with the &lt;code&gt;Thread&lt;/code&gt; prefix. This indicates that the function was called on a non-main thread and performed managed heap allocations.&lt;/p&gt;

&lt;p&gt;Select a function to inspect its allocation details.&lt;/p&gt;

&lt;p&gt;This allows developers to investigate allocation activity that may otherwise be difficult to identify when focusing only on the main thread.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can Developers Investigate Heap Growth and Potential Memory Leaks?
&lt;/h2&gt;

&lt;p&gt;Allocations on worker threads can also be relevant when investigating managed heap growth.&lt;/p&gt;

&lt;p&gt;If objects remain referenced and cannot be reclaimed by the garbage collector, the corresponding memory growth can be examined in the &lt;strong&gt;Heap Memory Leak Analysis&lt;/strong&gt; panel.&lt;/p&gt;

&lt;p&gt;Developers can locate the relevant function and compare two selected nodes to inspect changes in heap usage between them.&lt;/p&gt;

&lt;p&gt;This comparison helps developers investigate whether heap usage is increasing over time and narrow down the functions associated with that growth.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can Developers Inspect the Objects Behind Heap Allocations?
&lt;/h2&gt;

&lt;p&gt;After identifying a function of interest, click the blue button on the right to view the associated managed heap object types.&lt;/p&gt;

&lt;p&gt;The report displays the allocation size and object count for each type, helping developers understand which objects account for the observed memory usage.&lt;/p&gt;

&lt;p&gt;This additional detail can help developers determine whether a function is allocating too frequently or contributing significantly to heap growth.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Should Unity Developers Take Away?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Moving work to worker threads can reduce main-thread pressure, but managed heap allocations on those threads still need to be monitored.&lt;/li&gt;
&lt;li&gt;Unity Profiler may not expose all worker-thread allocation activity through the expected &lt;code&gt;GC.Alloc&lt;/code&gt; view.&lt;/li&gt;
&lt;li&gt;GOT Online Mono mode identifies non-main-thread allocation functions with the &lt;code&gt;Thread&lt;/code&gt; prefix.&lt;/li&gt;
&lt;li&gt;The Detailed Heap Allocations page provides function-level allocation details.&lt;/li&gt;
&lt;li&gt;Heap Memory Leak Analysis helps developers investigate memory growth and compare selected nodes.&lt;/li&gt;
&lt;li&gt;Object type, allocation size, and object count provide additional clues for diagnosing memory issues.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By including worker-thread allocations in managed memory analysis, Unity teams can investigate heap usage more comprehensively instead of focusing exclusively on the main thread.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Can worker threads allocate managed heap memory in Unity?
&lt;/h3&gt;

&lt;p&gt;Yes. Worker-thread code can allocate managed objects, depending on the operations it performs. These allocations can contribute to garbage collection overhead and sustained heap growth.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why might Unity Profiler not show worker-thread allocations in the expected &lt;code&gt;GC.Alloc&lt;/code&gt; view?
&lt;/h3&gt;

&lt;p&gt;The allocation activity described here may not be visible in the usual Unity Profiler view. GOT Online Mono mode provides additional statistics for investigating managed heap allocations made by non-main threads.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does GOT Online identify worker-thread allocation functions?
&lt;/h3&gt;

&lt;p&gt;In the Detailed Heap Allocations page, functions associated with allocations on non-main threads are marked with the &lt;code&gt;Thread&lt;/code&gt; prefix.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can GOT Online help investigate memory leaks involving worker threads?
&lt;/h3&gt;

&lt;p&gt;Yes. Developers can use Heap Memory Leak Analysis to examine heap growth associated with relevant functions and compare two selected nodes. Object types, allocation sizes, and object counts provide further information for investigation.&lt;/p&gt;

&lt;h2&gt;
  
  
  About GameOptim GOT Online
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GameOptim GOT Online&lt;/strong&gt; is a cloud-based performance analysis platform for Unity game development. It provides tools for investigating CPU, GPU, and memory performance, helping development teams identify bottlenecks and analyze issues using detailed test reports.&lt;/p&gt;

&lt;p&gt;Its Mono mode supports managed heap allocation analysis, including multithreaded allocation statistics, to help developers investigate memory behavior beyond the main thread.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>memory</category>
      <category>performance</category>
    </item>
    <item>
      <title>How Can Unity Teams Analyze Performance Across Multiple Test Devices at Once?</title>
      <dc:creator>GameOptim</dc:creator>
      <pubDate>Tue, 29 Sep 2026 07:56:47 +0000</pubDate>
      <link>https://dev.to/gameoptim/how-can-unity-teams-analyze-performance-across-multiple-test-devices-at-once-1opd</link>
      <guid>https://dev.to/gameoptim/how-can-unity-teams-analyze-performance-across-multiple-test-devices-at-once-1opd</guid>
      <description>&lt;h1&gt;
  
  
  How Can Unity Teams Analyze Performance Across Multiple Test Devices at Once?
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;As game teams increasingly run automated performance tests across multiple physical devices at the same time, the amount of test data can quickly grow from a few reports to dozens or even hundreds.&lt;/p&gt;

&lt;p&gt;Reviewing these reports one by one is time-consuming and makes it difficult to quickly determine which devices, test cases, or performance metrics require attention.&lt;/p&gt;

&lt;p&gt;GOT Online now provides &lt;strong&gt;Batch Test Analysis&lt;/strong&gt;, which automatically analyzes multiple test reports and generates an Excel file containing an overall test summary, optimization tasks, affected device models, test failures, and performance data.&lt;/p&gt;

&lt;p&gt;This allows development teams to move from reviewing individual reports to identifying common performance problems across an entire batch of automated tests.&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;A typical automated performance testing workflow may look like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build the game → Install it on multiple physical devices → Run automated tests → Collect performance data → Upload the data to GameOptim → Analyze the results&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Running tests in parallel across many devices can significantly reduce testing time and increase scenario coverage.&lt;/p&gt;

&lt;p&gt;However, this approach creates a new problem: &lt;strong&gt;how do you efficiently analyze dozens or hundreds of test results?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are usually two questions that development teams need to answer:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Which devices and test cases have performance problems?&lt;/li&gt;
&lt;li&gt;Did any functional problems occur during testing, such as crashes or blocked gameplay?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To address these problems, GOT Online introduces &lt;strong&gt;Batch Test Analysis&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  How Can Developers Analyze Multiple GOT Online Reports at Once?
&lt;/h1&gt;

&lt;p&gt;In an Overview mode report, developers can select &lt;strong&gt;Batch Test Analysis&lt;/strong&gt;, choose the test data to analyze, and click &lt;strong&gt;Start Analysis&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2fqx2eu89wexchrwsid5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2fqx2eu89wexchrwsid5.png" alt=" " width="799" height="209"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The system then automatically generates an Excel workbook containing five sheets:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Test Overview&lt;/li&gt;
&lt;li&gt;Optimization Queue Details&lt;/li&gt;
&lt;li&gt;Devices with Significant Performance Issues&lt;/li&gt;
&lt;li&gt;Test Failure Details&lt;/li&gt;
&lt;li&gt;Performance Reports&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each sheet provides a different perspective on the batch test results.&lt;/p&gt;

&lt;h1&gt;
  
  
  What Can the Test Overview Tell You?
&lt;/h1&gt;

&lt;p&gt;The &lt;strong&gt;Test Overview&lt;/strong&gt; sheet provides a high-level summary of the overall test results.&lt;/p&gt;

&lt;p&gt;For example, in the following test, the compatibility pass rate is &lt;strong&gt;40%&lt;/strong&gt;. Among the 10 analyzed tests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;4 passed the performance criteria&lt;/li&gt;
&lt;li&gt;5 failed the performance criteria&lt;/li&gt;
&lt;li&gt;1 exited unexpectedly due to a crash&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of opening each report individually, developers can use these summary results to quickly understand how the project performs across the tested devices.&lt;/p&gt;

&lt;p&gt;This is especially useful when a test batch contains a large number of devices.&lt;/p&gt;

&lt;h1&gt;
  
  
  How Can Batch Analysis Identify Common Performance Problems?
&lt;/h1&gt;

&lt;p&gt;The &lt;strong&gt;Optimization Queue Details&lt;/strong&gt; sheet summarizes performance problems that appear across the analyzed test data.&lt;/p&gt;

&lt;p&gt;Rather than simply reporting that a test failed, the analysis provides more detail about the performance bottlenecks, including the affected modules and devices.&lt;/p&gt;

&lt;p&gt;This gives the development team a clearer picture of which performance problems occur repeatedly across the test batch.&lt;/p&gt;

&lt;p&gt;It also makes optimization prioritization more meaningful.&lt;/p&gt;

&lt;p&gt;For example, a performance issue that appears across many devices may deserve higher priority than an issue that occurs in only one specific test case.&lt;/p&gt;

&lt;h1&gt;
  
  
  Can Batch Analysis Identify the Specific Devices Affected by a Bottleneck?
&lt;/h1&gt;

&lt;p&gt;Yes.&lt;/p&gt;

&lt;p&gt;The analysis can drill down to the specific &lt;strong&gt;device, test case, and performance module&lt;/strong&gt; associated with a performance problem.&lt;/p&gt;

&lt;p&gt;The report also provides links to the corresponding performance reports.&lt;/p&gt;

&lt;p&gt;Developers can therefore use the batch analysis to first identify the problematic devices and test cases, then open the individual reports for deeper investigation.&lt;/p&gt;

&lt;p&gt;This creates a two-step workflow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Batch analysis → Identify the problem → Open the detailed performance report&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  How Can Developers Find Crashes During Automated Testing?
&lt;/h1&gt;

&lt;p&gt;Performance is not the only issue that can occur during automated testing.&lt;/p&gt;

&lt;p&gt;A test may also encounter functional problems such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Game crashes&lt;/li&gt;
&lt;li&gt;Unexpected exits&lt;/li&gt;
&lt;li&gt;Gameplay tasks that cannot be completed&lt;/li&gt;
&lt;li&gt;Other test failures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a crash occurs during one of the test cases, the &lt;strong&gt;Test Failure Details&lt;/strong&gt; sheet records relevant information about that test.&lt;/p&gt;

&lt;p&gt;Developers can use information such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Device&lt;/li&gt;
&lt;li&gt;Test time&lt;/li&gt;
&lt;li&gt;Runtime duration before the crash&lt;/li&gt;
&lt;li&gt;Memory usage at the time of the crash&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;as clues for further investigation.&lt;/p&gt;

&lt;p&gt;This means that automated testing can provide more than performance data. It can also help teams identify functional failures encountered during the testing process.&lt;/p&gt;

&lt;h1&gt;
  
  
  What Performance Data Can Be Compared Across Test Cases?
&lt;/h1&gt;

&lt;p&gt;The &lt;strong&gt;Performance Reports&lt;/strong&gt; sheet provides an overview of important high-level performance metrics.&lt;/p&gt;

&lt;p&gt;These include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;FPS&lt;/li&gt;
&lt;li&gt;Memory&lt;/li&gt;
&lt;li&gt;Power consumption&lt;/li&gt;
&lt;li&gt;Temperature&lt;/li&gt;
&lt;li&gt;Network traffic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The report also provides scenario-level performance information, allowing developers to identify which gameplay scenarios may contain performance bottlenecks.&lt;/p&gt;

&lt;p&gt;This makes it easier to connect a performance problem with the specific scenario in which it occurs.&lt;/p&gt;

&lt;h1&gt;
  
  
  When Is Batch Test Analysis Useful?
&lt;/h1&gt;

&lt;p&gt;Batch Test Analysis is particularly useful for workflows that combine &lt;strong&gt;GOT Online with automated testing across multiple physical devices&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Compared with simply checking device compatibility, this approach provides more targeted performance information.&lt;/p&gt;

&lt;p&gt;Instead of asking only:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Does the game run on this device?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;developers can ask:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Which performance problems occur on which devices, how frequently do they occur, and which problems should we optimize first?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At the same time, crash information collected during the test provides another layer of information that development teams often need when running automated tests.&lt;/p&gt;

&lt;h1&gt;
  
  
  What Are the Requirements for Batch Test Analysis?
&lt;/h1&gt;

&lt;p&gt;Batch Test Analysis is available for GOT Online test data generated &lt;strong&gt;on or after August 14&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The following conditions must be met:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each individual test must run for at least &lt;strong&gt;3 minutes&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;At least &lt;strong&gt;5 test data records&lt;/strong&gt; are required.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When these conditions are satisfied, the Batch Test Analysis feature can be used to analyze the test batch.&lt;/p&gt;

&lt;h1&gt;
  
  
  What Should Teams Consider When Using Poco Automation?
&lt;/h1&gt;

&lt;p&gt;When using the &lt;strong&gt;Poco-based automated testing scripts&lt;/strong&gt; with GOT Online's Overview mode, the scripts may introduce additional CPU overhead.&lt;/p&gt;

&lt;p&gt;Development teams should therefore also consider optimizing the Poco automation scripts themselves.&lt;/p&gt;

&lt;p&gt;Otherwise, some of the CPU workload observed during the test may come from the automation process rather than the game itself.&lt;/p&gt;

&lt;p&gt;This is particularly important when evaluating CPU-related performance metrics.&lt;/p&gt;

&lt;h1&gt;
  
  
  What Should Unity Teams Take Away?
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Running performance tests across many physical devices provides broader coverage but also creates a large amount of data to analyze.&lt;/li&gt;
&lt;li&gt;Batch analysis can identify common performance problems without requiring developers to manually inspect every report.&lt;/li&gt;
&lt;li&gt;Performance issues can be traced to specific devices, test cases, and performance modules.&lt;/li&gt;
&lt;li&gt;Crash information can be analyzed alongside performance test results.&lt;/li&gt;
&lt;li&gt;FPS, memory, power, temperature, and network data provide a high-level view of performance across the test batch.&lt;/li&gt;
&lt;li&gt;Individual performance reports can then be opened for deeper investigation.&lt;/li&gt;
&lt;li&gt;When using Poco-based automation, teams should account for the CPU overhead introduced by the automation scripts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  FAQ
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Q1. What is Batch Test Analysis in GOT Online?
&lt;/h3&gt;

&lt;p&gt;Batch Test Analysis allows developers to analyze multiple GOT Online test reports together instead of reviewing them individually. It generates an Excel workbook containing test summaries, optimization information, affected devices, test failures, and performance data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q2. How many test reports are required for Batch Test Analysis?
&lt;/h3&gt;

&lt;p&gt;At least &lt;strong&gt;5 test data records&lt;/strong&gt; are required, and each individual test must be at least &lt;strong&gt;3 minutes long&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q3. Can Batch Test Analysis identify which devices have performance problems?
&lt;/h3&gt;

&lt;p&gt;Yes. The analysis can identify specific devices, test cases, and performance modules associated with performance problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q4. Can the feature detect crashes?
&lt;/h3&gt;

&lt;p&gt;Yes. If a test case crashes or exits unexpectedly, the test failure information can be included in the batch analysis. Developers can use device information, test time, runtime duration, and memory usage as clues for further investigation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q5. What performance metrics are included in the batch analysis?
&lt;/h3&gt;

&lt;p&gt;The performance overview includes high-level information such as FPS, memory, power consumption, temperature, and network traffic. Scenario-level performance information is also provided.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q6. Does Poco automation affect performance measurements?
&lt;/h3&gt;

&lt;p&gt;Potentially. Poco-based automation scripts used with GOT Online Overview mode may introduce additional CPU overhead. Teams should consider optimizing the automation scripts when interpreting CPU-related performance results.&lt;/p&gt;

&lt;h1&gt;
  
  
  About GameOptim GOT Online
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;GameOptim GOT Online&lt;/strong&gt; is a cloud-based performance analysis platform for Unity game development. It helps development teams collect and analyze performance data across areas such as CPU, GPU, memory, power, temperature, and network performance.&lt;/p&gt;

&lt;p&gt;With automated testing and batch analysis, teams can move from manually reviewing individual performance reports toward a more scalable performance testing workflow.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>performance</category>
      <category>testing</category>
    </item>
    <item>
      <title>How Can Unity Developers Define Test Intervals and Automate GOT Online Data Uploads?</title>
      <dc:creator>GameOptim</dc:creator>
      <pubDate>Wed, 23 Sep 2026 07:53:45 +0000</pubDate>
      <link>https://dev.to/gameoptim/how-can-unity-developers-define-test-intervals-and-automate-got-online-data-uploads-9aj</link>
      <guid>https://dev.to/gameoptim/how-can-unity-developers-define-test-intervals-and-automate-got-online-data-uploads-9aj</guid>
      <description>&lt;p&gt;GOT Online now supports two new runtime capabilities: developers can upload test data through an API and use runtime Tags to define custom test intervals for report statistics. These features make it easier to integrate GOT Online with automated testing workflows and analyze performance across different gameplay scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;GOT Online has added two practical features for Unity development and performance testing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Upload test data through an API at runtime.&lt;/li&gt;
&lt;li&gt;Define custom test intervals with runtime Tags for interval-based statistics in online reports.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These features are particularly useful when a single test covers multiple scenes or gameplay states, or when teams want to integrate performance profiling into automated testing pipelines.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Can Unity Developers Compare Performance Across Different Test Scenarios?
&lt;/h2&gt;

&lt;p&gt;In the &lt;strong&gt;Overview&lt;/strong&gt; mode of a GOT Online report, many pages provide important performance metrics such as:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fztr39bg25mw5qdtvf8i3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fztr39bg25mw5qdtvf8i3.png" alt=" " width="800" height="103"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most of these metrics are calculated as averages across the entire test. This provides an overview of overall performance, but a single test may cover multiple scenes or gameplay scenarios with very different performance characteristics.&lt;/p&gt;

&lt;p&gt;For example, one scene may have relatively low CPU usage while another may contain more complex gameplay logic and significantly higher CPU time.&lt;/p&gt;

&lt;p&gt;If all data is averaged together, performance spikes in a specific scenario can be diluted by the rest of the test.&lt;/p&gt;

&lt;p&gt;To make these differences easier to identify, GOT Online now supports &lt;strong&gt;test interval statistics&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Different gameplay scenarios can be treated as separate intervals, allowing developers to analyze performance for each interval independently.&lt;/p&gt;

&lt;p&gt;This provides a more detailed view of how performance changes throughout a test instead of relying only on the overall average.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Can Developers Define Custom Test Intervals at Runtime?
&lt;/h2&gt;

&lt;p&gt;Scene-based intervals may not always be detailed enough.&lt;/p&gt;

&lt;p&gt;Even within the same Unity scene, different gameplay states can produce very different performance characteristics. For example, a scene might include exploration, combat, and UI-heavy interactions.&lt;/p&gt;

&lt;p&gt;To provide more flexibility, GOT Online introduces the &lt;code&gt;UWAEngine.Tag&lt;/code&gt; API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;UWAEngine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Tag&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Developers can call this function at runtime to mark a specific test interval.&lt;/p&gt;

&lt;p&gt;Once a Tag is applied, it will override the original Unity scene name for the corresponding interval.&lt;/p&gt;

&lt;p&gt;As a result, the scene name displayed in the GOT Online report and the interval statistics will use the specified &lt;strong&gt;Tag&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This allows development teams to define performance intervals based on actual gameplay states rather than relying only on Unity scene transitions.&lt;/p&gt;

&lt;p&gt;For example, instead of analyzing an entire scene as one interval, developers can define separate intervals such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exploration&lt;/li&gt;
&lt;li&gt;Combat&lt;/li&gt;
&lt;li&gt;Boss Fight&lt;/li&gt;
&lt;li&gt;Inventory&lt;/li&gt;
&lt;li&gt;UI Interaction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The exact Tags depend on the team's testing workflow and what they want to measure.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Can Developers Automatically Upload GOT Online Test Data?
&lt;/h2&gt;

&lt;p&gt;Performance testing is increasingly being integrated with automated testing workflows.&lt;/p&gt;

&lt;p&gt;Many teams are combining GOT with automated testing tools to reduce repetitive manual work and make performance testing easier to run at scale.&lt;/p&gt;

&lt;p&gt;Previously, after a test was completed, developers needed to manually click the upload button to send the collected data to GOT Online.&lt;/p&gt;

&lt;p&gt;The new runtime upload API allows this step to be automated.&lt;/p&gt;

&lt;p&gt;After configuring the required project and account information in advance, test data can be uploaded automatically without manual interaction.&lt;/p&gt;

&lt;p&gt;The API is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;UWAEngine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Upload&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Upload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;pwd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;timeLimitSec&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Upload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;pwd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;projectName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;timeLimitSec&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The parameters are documented in the SDK documentation.&lt;/p&gt;

&lt;p&gt;This makes the API suitable for automated testing workflows where a test can be executed, data can be collected, and the resulting performance data can then be uploaded automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Should Developers Know About the Runtime Upload API?
&lt;/h2&gt;

&lt;p&gt;There are two important limitations to keep in mind.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The automatic upload feature is only available for GOT Online.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is designed specifically for uploading performance test data to the GOT Online service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. IL2CPP compatibility&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When using the IL2CPP scripting backend, the API supports &lt;strong&gt;Unity 2018 and later&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;During the upload process, the application displays an &lt;strong&gt;uploading&lt;/strong&gt; status. After the upload is completed successfully, it displays a &lt;strong&gt;completed&lt;/strong&gt; status.&lt;/p&gt;

&lt;p&gt;This provides basic feedback during automated or semi-automated testing workflows.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Do Runtime Tags and Automatic Upload Work Together?
&lt;/h2&gt;

&lt;p&gt;These two features can also be useful when building a more automated performance testing process.&lt;/p&gt;

&lt;p&gt;A typical workflow could be:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run automated test → Mark gameplay intervals with &lt;code&gt;UWAEngine.Tag&lt;/code&gt; → Collect performance data → Upload data with &lt;code&gt;UWAEngine.Upload&lt;/code&gt; → Analyze interval statistics in GOT Online&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With runtime Tags, developers can define meaningful performance intervals during the test itself.&lt;/p&gt;

&lt;p&gt;With runtime upload, the resulting data can be sent to GOT Online automatically.&lt;/p&gt;

&lt;p&gt;Together, they reduce manual steps while making performance data more structured and easier to compare across different gameplay scenarios.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Can Unity Developers Take Away?
&lt;/h2&gt;

&lt;p&gt;The new GOT Online runtime APIs address two common problems in performance testing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem 1: Overall averages can hide local performance issues.&lt;/strong&gt;&lt;br&gt;
Runtime Tags allow developers to divide a test into meaningful intervals and analyze each interval separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem 2: Manual data uploads add unnecessary steps to automated testing.&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;UWAEngine.Upload&lt;/code&gt; allows test data to be uploaded automatically after testing.&lt;/p&gt;

&lt;p&gt;For teams building automated Unity performance testing workflows, these capabilities can make test data collection and analysis more consistent and easier to integrate into existing pipelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Can &lt;code&gt;UWAEngine.Tag&lt;/code&gt; be used to define performance intervals?
&lt;/h3&gt;

&lt;p&gt;Yes. &lt;code&gt;UWAEngine.Tag(string tag)&lt;/code&gt; can be called at runtime to mark test intervals. The specified Tag overrides the original Unity scene name for the corresponding interval in GOT Online.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does GOT Online only support scene-based performance analysis?
&lt;/h3&gt;

&lt;p&gt;No. Runtime Tags allow developers to define more granular intervals within the same Unity scene based on gameplay states or other testing requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can GOT Online test data be uploaded automatically?
&lt;/h3&gt;

&lt;p&gt;Yes. &lt;code&gt;UWAEngine.Upload&lt;/code&gt; can upload test data automatically after the required project and account information has been configured.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does automatic upload support IL2CPP?
&lt;/h3&gt;

&lt;p&gt;Yes. For IL2CPP projects, the upload API supports Unity 2018 and later.&lt;/p&gt;




&lt;h2&gt;
  
  
  About GameOptim GOT Online
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GameOptim GOT Online&lt;/strong&gt; is a cloud-based performance analysis platform for Unity game development. It provides detailed performance data and analysis across areas such as CPU, GPU, memory, Lua, and rendering.&lt;/p&gt;

&lt;p&gt;By combining runtime data collection with cloud-based analysis, GOT Online helps development teams identify performance issues, compare different test scenarios, and support performance optimization throughout development and testing.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>performance</category>
      <category>testing</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>How Can Unity Developers Identify the Causes of GPU Pressure on Mobile Devices?</title>
      <dc:creator>GameOptim</dc:creator>
      <pubDate>Mon, 21 Sep 2026 09:16:30 +0000</pubDate>
      <link>https://dev.to/gameoptim/how-can-unity-developers-identify-the-causes-of-gpu-pressure-on-mobile-devices-1mbn</link>
      <guid>https://dev.to/gameoptim/how-can-unity-developers-identify-the-causes-of-gpu-pressure-on-mobile-devices-1mbn</guid>
      <description>&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;As mobile games continue to pursue higher visual quality, GPU optimization has become increasingly important. Differences between mobile GPU architectures can make GPU bottlenecks difficult to identify and optimize.&lt;/p&gt;

&lt;p&gt;GameOptim GOT Online GPU Mode provides a set of tools for analyzing GPU pressure from multiple perspectives, including GPU rendering, bandwidth, rendering resources, Overdraw, and device temperature. These metrics help Unity developers move from identifying GPU pressure to locating the specific rendering workload behind it.&lt;/p&gt;

&lt;p&gt;This article introduces the key GPU analysis features and explains how developers can use them to investigate common GPU performance issues.&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Higher-quality visuals often mean more complex rendering workloads. More geometry, textures, shader calculations, transparency, and post-processing can all increase GPU pressure on mobile devices.&lt;/p&gt;

&lt;p&gt;At the same time, different GPU vendors and architectures expose different performance metrics, making it difficult to rely on a single indicator when investigating GPU bottlenecks.&lt;/p&gt;

&lt;p&gt;GameOptim GOT Online GPU Mode provides several analysis modules designed to break GPU pressure down into more actionable data.&lt;/p&gt;

&lt;p&gt;The main capabilities include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance Brief:&lt;/strong&gt; Quickly identify areas of high GPU pressure and prioritize optimization tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPU Analysis:&lt;/strong&gt; Analyze GPU pressure from rendering and bandwidth perspectives.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rendering Resource Analysis:&lt;/strong&gt; Investigate how textures and meshes are loaded and used.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overdraw Snapshot:&lt;/strong&gt; Locate the sources of high Overdraw more easily.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPU Temperature:&lt;/strong&gt; Determine whether GPU workload is a major contributor to device heating.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  How Can Developers Quickly Identify GPU Pressure?
&lt;/h1&gt;

&lt;p&gt;The Performance Brief provides a high-level overview of GPU performance during testing.&lt;/p&gt;

&lt;p&gt;GameOptim displays FPS and GPU Clocks and highlights GPU Bound frames with a light red background.&lt;/p&gt;

&lt;p&gt;GPU Bound indicates a high GPU workload, where the number of GPU clock cycles required for computation is high enough that the GPU may not be able to sustain the target frame rate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1kzgbtwqf9x8rt71xeo2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1kzgbtwqf9x8rt71xeo2.png" alt=" " width="800" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Performance Brief also summarizes metrics from four areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GPU performance&lt;/li&gt;
&lt;li&gt;Rendering statistics&lt;/li&gt;
&lt;li&gt;Texture resource analysis&lt;/li&gt;
&lt;li&gt;Mesh resource analysis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also provides corresponding optimization tasks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnp3ie0uthcroppl7cafs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnp3ie0uthcroppl7cafs.png" alt=" " width="799" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The purpose of the brief is not to replace detailed analysis, but to help developers quickly filter a large number of performance metrics and identify high-priority optimization tasks.&lt;/p&gt;

&lt;p&gt;When a metric requires deeper investigation, developers can move into the corresponding analysis module.&lt;/p&gt;

&lt;h1&gt;
  
  
  How Can GPU Rendering Metrics Reveal the Source of GPU Pressure?
&lt;/h1&gt;

&lt;p&gt;The GPU Analysis module examines GPU pressure from two perspectives: &lt;strong&gt;rendering&lt;/strong&gt; and &lt;strong&gt;bandwidth&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The available metrics may differ between GPU vendors because GameOptim collects different parameters from different GPU architectures.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can GPU Clocks Be Used to Identify Rendering Pressure?
&lt;/h2&gt;

&lt;p&gt;GPU Clocks is one of the primary metrics for evaluating GPU performance.&lt;/p&gt;

&lt;p&gt;By examining the GPU Clocks curve, developers can quickly identify scenes where GPU pressure is high.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frxf3ti725wahgbeuju4s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frxf3ti725wahgbeuju4s.png" alt=" " width="799" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GameOptim also provides average values and performance trends for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GPU Shaded&lt;/li&gt;
&lt;li&gt;GPU Shader Cycles&lt;/li&gt;
&lt;li&gt;GPU Primitive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When GPU Clocks is high in a particular scene, these metrics can help developers determine which part of the rendering workload is contributing to the GPU pressure and identify potential optimization directions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0ifrk7pyyfdlvev33ctu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0ifrk7pyyfdlvev33ctu.png" alt=" " width="799" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What Is the Difference Between Shader Instructions and Shader Cycles?
&lt;/h1&gt;

&lt;p&gt;Starting with GameOptim SDK 2.4.9, the Mali GPU report includes &lt;strong&gt;GPU Shader Instructions&lt;/strong&gt;, which represents the number of shader instructions executed by the GPU per frame.&lt;/p&gt;

&lt;p&gt;GPU Shader Instructions and Shader Cycles describe different aspects of shader execution.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Shader Cycles:&lt;/strong&gt; The processing cycles required when the shader actually runs on the GPU.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shader Instructions:&lt;/strong&gt; The instruction operations contained in the shader.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F92z6p0i7fsmcbcp8s7vn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F92z6p0i7fsmcbcp8s7vn.png" alt=" " width="800" height="179"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The number of processing cycles required for the same instructions can differ between GPUs with different performance characteristics.&lt;/p&gt;

&lt;p&gt;Therefore, Shader Instructions can help developers understand the complexity of the shader itself, while Shader Cycles provide information about the actual processing workload on the GPU.&lt;/p&gt;

&lt;h1&gt;
  
  
  How Can Culled Primitives Be Broken Down Further?
&lt;/h1&gt;

&lt;p&gt;GameOptim SDK 2.4.9 also provides a more detailed breakdown of &lt;strong&gt;Culled Primitives&lt;/strong&gt; under GPU Primitive.&lt;/p&gt;

&lt;p&gt;Three additional metrics are available:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;FacingCullingPrimitives:&lt;/strong&gt; Number of primitives removed through facing culling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FrustumCullingPrimitives:&lt;/strong&gt; Number of primitives removed through frustum culling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CoverageCullingPrimitives:&lt;/strong&gt; Number of small primitives removed through coverage culling.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foy87qvbspxxlvnusf5eh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foy87qvbspxxlvnusf5eh.png" alt=" " width="800" height="183"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These metrics help developers understand the composition of Culled Primitives and identify rendering resources that may be causing unnecessary GPU workload in specific scenes.&lt;/p&gt;

&lt;h1&gt;
  
  
  How Can Developers Analyze GPU Bandwidth Pressure?
&lt;/h1&gt;

&lt;p&gt;High GPU read and write bandwidth can contribute to significant heat generation and power consumption, making bandwidth an important area to investigate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flxvkpeomqge7nslzpv71.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flxvkpeomqge7nslzpv71.png" alt=" " width="800" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Starting with GameOptim SDK 2.4.9, &lt;strong&gt;Read Total&lt;/strong&gt; is further divided into more detailed metrics.&lt;/p&gt;

&lt;p&gt;For Mali GPUs, the report includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Front-end Read&lt;/li&gt;
&lt;li&gt;LoadStore Read&lt;/li&gt;
&lt;li&gt;Texture Read&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These correspond to bandwidth used by the GPU's Tile Unit, Load/Store Unit, and Texture Unit, including reads of TileList data, vertex input attributes, Uniform data, color/depth data, and texture data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe5lggacya62g6a0mnqyg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe5lggacya62g6a0mnqyg.png" alt=" " width="798" height="172"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For Adreno GPUs, Read Total is divided into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vertex Read&lt;/li&gt;
&lt;li&gt;SP Read&lt;/li&gt;
&lt;li&gt;Texture Read&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These metrics similarly cover reads of TileList data, vertex input attributes, Uniform data, color/depth data, and texture data.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why Does Cache Hit Rate Affect GPU Read Bandwidth?
&lt;/h1&gt;

&lt;p&gt;For different GPU architectures, Read Total depends on the amount of data processed by the relevant GPU units per second as well as the hit rates of the L1 and L2 caches.&lt;/p&gt;

&lt;p&gt;When the total amount of data remains unchanged, a higher cache hit rate results in a lower Read Total because more data can be served from the cache instead of being read from farther memory.&lt;/p&gt;

&lt;p&gt;GameOptim also provides related metrics such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GPU Texture Filter&lt;/li&gt;
&lt;li&gt;GPU Stall&lt;/li&gt;
&lt;li&gt;GPU Texture Cache Miss&lt;/li&gt;
&lt;li&gt;GPU Primitive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These metrics can help developers further investigate the source of GPU bandwidth pressure.&lt;/p&gt;

&lt;h1&gt;
  
  
  How Can Developers Check Whether Textures and Meshes Are Being Used Efficiently?
&lt;/h1&gt;

&lt;p&gt;The more textures and meshes participate in rendering, and the more frequently they are sampled, the more likely memory usage, GPU bandwidth, and GPU Clocks are to increase.&lt;/p&gt;

&lt;p&gt;To understand whether rendering resources are actually being used efficiently, developers can enable texture and mesh resource analysis and inspect their specific usage.&lt;/p&gt;

&lt;h1&gt;
  
  
  How Can Texture Resource Analysis Identify Unused Textures?
&lt;/h1&gt;

&lt;p&gt;The texture resource analysis page provides information such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Texture memory usage&lt;/li&gt;
&lt;li&gt;Texture count&lt;/li&gt;
&lt;li&gt;Texture dimensions&lt;/li&gt;
&lt;li&gt;Texture rendering utilization&lt;/li&gt;
&lt;li&gt;Mipmap status&lt;/li&gt;
&lt;li&gt;Mipmap sampling rate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpzg1zxhrib5vtuyeeana.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpzg1zxhrib5vtuyeeana.png" alt=" " width="799" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fimaq8t88hley78q7so7r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fimaq8t88hley78q7so7r.png" alt=" " width="800" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Texture rendering utilization can help identify textures that remain loaded in memory but never participate in rendering.&lt;/p&gt;

&lt;p&gt;Developers can then investigate whether the unused resources are related to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Invisible rendering objects&lt;/li&gt;
&lt;li&gt;Inefficient asset packaging&lt;/li&gt;
&lt;li&gt;Unnecessary loading strategies&lt;/li&gt;
&lt;li&gt;Other resource management issues&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Can Mipmap Sampling Reveal Oversized Textures?
&lt;/h1&gt;

&lt;p&gt;Yes. A low Mipmap Level 0 sampling rate can indicate that a texture is larger than necessary for its actual usage.&lt;/p&gt;

&lt;p&gt;GameOptim uses a &lt;strong&gt;5%&lt;/strong&gt; Level 0 sampling rate as a reference point. If a texture's Level 0 sampling rate is below 5%, developers can investigate whether its resolution is unnecessarily high.&lt;/p&gt;

&lt;p&gt;Reducing the texture resolution can lower memory pressure without necessarily affecting the rendered result when the higher-resolution Mipmap level is rarely used.&lt;/p&gt;

&lt;h1&gt;
  
  
  How Can Mesh Resource Analysis Identify Overly Detailed Geometry?
&lt;/h1&gt;

&lt;p&gt;The mesh resource analysis page provides rendering utilization as well as &lt;strong&gt;minimum rendering density&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Meshes with 0% rendering utilization can be investigated in a similar way to unused textures.&lt;/p&gt;

&lt;p&gt;Minimum rendering density provides another way to determine whether a mesh contains excessive geometric detail.&lt;/p&gt;

&lt;p&gt;Rendering density represents the number of mesh vertices within an average area of &lt;strong&gt;10,000 pixels&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If the value is above &lt;strong&gt;1,000&lt;/strong&gt;, the mesh may contain excessive geometric detail for the relatively small screen area it occupies.&lt;/p&gt;

&lt;p&gt;If the minimum rendering density remains above 1,000, developers can consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reducing the mesh polygon count&lt;/li&gt;
&lt;li&gt;Applying LOD&lt;/li&gt;
&lt;li&gt;Reviewing whether the asset needs to be rendered at its current level of detail&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  How Can an Overdraw Snapshot Help Locate GPU Pressure?
&lt;/h1&gt;

&lt;p&gt;Overdraw represents the number of times the screen is filled during a frame.&lt;/p&gt;

&lt;p&gt;Transparent objects can cause the same pixel to be rendered multiple times, making them an important source of high Overdraw and potentially increasing GPU workload and device temperature.&lt;/p&gt;

&lt;p&gt;In the Overdraw Snapshot module, GameOptim calculates overall Overdraw using &lt;strong&gt;Fragment Shaded&lt;/strong&gt; and a fixed resolution of &lt;strong&gt;1920 × 1080&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;During a GPU Mode test, developers can manually dump a specific scene to capture its detailed Overdraw information.&lt;/p&gt;

&lt;p&gt;The Overdraw Snapshot module then displays Overdraw information for each camera in the captured frame.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Overlay-UI (UWA)&lt;/strong&gt; camera represents the Overdraw generated by the Overlay portion of UGUI, including UI elements that are not attached to any camera.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6sxhf5dk7lg55nw4nrdd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6sxhf5dk7lg55nw4nrdd.png" alt=" " width="799" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The module also provides an Overdraw heatmap below the chart.&lt;/p&gt;

&lt;p&gt;Brighter areas indicate pixels that were filled more times during the current frame, meaning higher Overdraw and potentially greater GPU pressure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmaapewynwovft5tsfm5k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmaapewynwovft5tsfm5k.png" alt=" " width="799" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By comparing the scene screenshot with the Overdraw heatmap, developers can more easily identify which visual elements are responsible for high Overdraw.&lt;/p&gt;

&lt;h1&gt;
  
  
  How Can Developers Determine Whether GPU Pressure Is Causing Device Heating?
&lt;/h1&gt;

&lt;p&gt;High GPU workload can contribute to increased device temperature.&lt;/p&gt;

&lt;p&gt;GameOptim records GPU, CPU, and battery temperatures, allowing developers to determine whether GPU workload is a major contributor to device heating.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0peo4ct5i6xmde6cgnuk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0peo4ct5i6xmde6cgnuk.png" alt=" " width="800" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If GPU pressure is confirmed as a major factor, developers can further investigate related metrics such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;FPS&lt;/li&gt;
&lt;li&gt;GPU Clocks&lt;/li&gt;
&lt;li&gt;GPU Bandwidth&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Power consumption is also closely related to GPU temperature and can provide another useful signal when investigating energy consumption and thermal issues.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9gapqwao6n8h4bufnq0q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9gapqwao6n8h4bufnq0q.png" alt=" " width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, GPU temperature should not be analyzed in isolation.&lt;/p&gt;

&lt;p&gt;Because the CPU and GPU are physically close on mobile devices, high CPU workload and the resulting heat can also contribute to higher GPU temperature.&lt;/p&gt;

&lt;p&gt;Therefore, when investigating GPU-related thermal problems, developers should also consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GPU performance pressure&lt;/li&gt;
&lt;li&gt;GPU bandwidth&lt;/li&gt;
&lt;li&gt;CPU main-thread workload&lt;/li&gt;
&lt;li&gt;CPU worker-thread workload&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A broader view can help distinguish between GPU-driven and CPU-driven thermal issues.&lt;/p&gt;

&lt;h1&gt;
  
  
  What Should Unity Developers Take Away?
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Use GPU Clocks to identify scenes with high GPU pressure, then drill down into more specific rendering metrics.&lt;/li&gt;
&lt;li&gt;Use Shader Instructions and Shader Cycles together to understand shader complexity and actual GPU processing workload.&lt;/li&gt;
&lt;li&gt;Break down Culled Primitives to identify where GPU-side culling is occurring.&lt;/li&gt;
&lt;li&gt;Analyze GPU bandwidth from the relevant GPU-unit metrics and consider cache behavior.&lt;/li&gt;
&lt;li&gt;Check texture and mesh utilization to identify resources that are loaded but rarely or never rendered.&lt;/li&gt;
&lt;li&gt;Use Mipmap sampling rates and mesh rendering density to identify resources with potentially excessive resolution or geometric complexity.&lt;/li&gt;
&lt;li&gt;Use Overdraw snapshots and heatmaps to locate transparent objects and other sources of excessive pixel processing.&lt;/li&gt;
&lt;li&gt;When investigating device heating, analyze GPU, CPU, bandwidth, power, and temperature together rather than treating GPU temperature as an isolated metric.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  FAQ
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Q1. What does GPU Clocks indicate?
&lt;/h3&gt;

&lt;p&gt;GPU Clocks is a primary metric for evaluating GPU performance. A high GPU Clocks value can indicate that the GPU is under significant processing pressure in a particular scene.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q2. What is the difference between Shader Instructions and Shader Cycles?
&lt;/h3&gt;

&lt;p&gt;Shader Instructions represents the shader instruction operations, while Shader Cycles represents the processing cycles required when the shader executes on the GPU. The same instructions may require different numbers of processing cycles on GPUs with different performance characteristics.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q3. Why should developers check Culled Primitives?
&lt;/h3&gt;

&lt;p&gt;Breaking down Culled Primitives into Facing Culling, Frustum Culling, and Coverage Culling helps developers understand why primitives are being removed and identify potential sources of unnecessary GPU workload.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q4. How can developers find unused textures and meshes?
&lt;/h3&gt;

&lt;p&gt;Rendering utilization can reveal resources that remain loaded but do not participate in rendering during the test. Developers can then investigate whether the resources are unnecessary, incorrectly packaged, or simply not covered by the test scenario.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q5. What does a low Mipmap Level 0 sampling rate indicate?
&lt;/h3&gt;

&lt;p&gt;A low Level 0 sampling rate may indicate that the texture resolution is higher than required for its actual rendering usage. GameOptim uses 5% as a reference point for identifying textures that may warrant further investigation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q6. How can Overdraw Snapshots help with GPU optimization?
&lt;/h3&gt;

&lt;p&gt;The Overdraw Snapshot module provides per-camera Overdraw information and a heatmap. Brighter areas indicate more pixel fills, allowing developers to compare the heatmap with the scene and locate visual elements responsible for high Overdraw.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q7. Is high GPU temperature always caused by GPU workload?
&lt;/h3&gt;

&lt;p&gt;Not necessarily. High CPU workload can also contribute to device heating, and the CPU and GPU are physically close on mobile devices. GPU temperature should therefore be analyzed together with GPU pressure, bandwidth, CPU workload, power consumption, and other relevant metrics.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>performance</category>
      <category>mobile</category>
      <category>gamedev</category>
    </item>
  </channel>
</rss>
