<?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 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>
    <item>
      <title>Optimizing Canvas.BuildBatch Cost via Static/Dynamic UI Separation</title>
      <dc:creator>GameOptim</dc:creator>
      <pubDate>Thu, 17 Sep 2026 06:52:11 +0000</pubDate>
      <link>https://dev.to/gameoptim/optimizing-canvasbuildbatch-cost-via-staticdynamic-ui-separation-5a1h</link>
      <guid>https://dev.to/gameoptim/optimizing-canvasbuildbatch-cost-via-staticdynamic-ui-separation-5a1h</guid>
      <description>&lt;h2&gt;
  
  
  Problem / Scenario
&lt;/h2&gt;

&lt;p&gt;After optimizing DrawCall and Overdraw on a weapon UI panel, the rendering side looked good. But CPU profiling revealed a significant logic-side bottleneck: &lt;code&gt;Canvas.BuildBatch&lt;/code&gt; was taking too long, causing the main thread to stall waiting for the worker thread.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Observed
&lt;/h2&gt;

&lt;p&gt;We used &lt;strong&gt;GOT Online&lt;/strong&gt; (GameOptim's performance optimization tool) for profiling, as Unity Editor's built-in Profiler adds its own overhead which can skew results.&lt;/p&gt;

&lt;p&gt;After a 10-minute test, under &lt;strong&gt;Engine → UI&lt;/strong&gt;, we found:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Rendering.EmitWorldScreenspaceCameraGeometry&lt;/code&gt;: &lt;strong&gt;0.43 ms&lt;/strong&gt; CPU cost&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Understanding the Signal
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;EmitWorldScreenspaceCameraGeometry&lt;/code&gt; is a low-level UGUI rendering function that executes after &lt;code&gt;Canvas.BuildBatch&lt;/code&gt; completes on the worker thread. High cost in this function on the main thread indicates that &lt;strong&gt;BuildBatch on the worker thread is the actual bottleneck&lt;/strong&gt;—the main thread is waiting.&lt;/p&gt;

&lt;p&gt;This is a useful diagnostic shortcut: if you see high &lt;code&gt;EmitWorldScreenspaceCameraGeometry&lt;/code&gt; time, BuildBatch is your culprit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Root Cause Analysis
&lt;/h2&gt;

&lt;p&gt;The weapon UI panel had a grid of weapon icons (static) plus several rotating circular background elements (dynamic). All lived under the same child Canvas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem chain:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Rotating circles change their transform every frame&lt;/li&gt;
&lt;li&gt;Changed elements are marked as dirty&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Canvas.BuildBatch&lt;/code&gt; must rebuild batches for the &lt;strong&gt;entire Canvas&lt;/strong&gt;, not just the dirty elements&lt;/li&gt;
&lt;li&gt;Static elements (icons, backgrounds, frames) get re-batched every frame despite never changing&lt;/li&gt;
&lt;li&gt;The more elements on the Canvas, the more expensive each rebuild&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is a classic case of &lt;strong&gt;paying for work you don't need&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimization: Static/Dynamic Separation
&lt;/h2&gt;

&lt;p&gt;The principle is simple: &lt;strong&gt;put elements that change at different frequencies on different Canvases.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;

&lt;p&gt;We split the UI into two Canvases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic Canvas:&lt;/strong&gt; only the rotating circle elements

&lt;ul&gt;
&lt;li&gt;Rebuilds every frame&lt;/li&gt;
&lt;li&gt;Small element count → fast rebuild&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Static Canvas:&lt;/strong&gt; weapon icons, frames, backgrounds, all non-animated elements

&lt;ul&gt;
&lt;li&gt;Rarely rebuilds (only when content actually changes)&lt;/li&gt;
&lt;li&gt;Large element count → but almost never rebuilt&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why It Works
&lt;/h3&gt;

&lt;p&gt;BuildBatch cost scales with the number of elements on the Canvas. By isolating frequently-changing elements to their own small Canvas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Per-frame BuildBatch processes far fewer elements&lt;/li&gt;
&lt;li&gt;The large static Canvas rarely triggers rebuilds&lt;/li&gt;
&lt;li&gt;Total BuildBatch work across both Canvases is dramatically less than one Canvas rebuilding everything every frame&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;After the change:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Rendering.EmitWorldScreenspaceCameraGeometry&lt;/code&gt;: &lt;strong&gt;0.43 ms → 0.09 ms&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;~79% reduction in BuildBatch-related main-thread cost&lt;/li&gt;
&lt;li&gt;The main thread is essentially no longer waiting on the worker thread&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Takeaway
&lt;/h2&gt;

&lt;p&gt;Static/dynamic separation is one of the highest-impact, lowest-effort UGUI optimizations when BuildBatch is a bottleneck.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to diagnose:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Profile with a device-side tool (GOT Online or similar) for accurate numbers&lt;/li&gt;
&lt;li&gt;Look for high &lt;code&gt;EmitWorldScreenspaceCameraGeometry&lt;/code&gt; cost&lt;/li&gt;
&lt;li&gt;This correlates with slow &lt;code&gt;Canvas.BuildBatch&lt;/code&gt; on the worker thread&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How to fix:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify elements by update frequency (static, occasional, every-frame)&lt;/li&gt;
&lt;li&gt;Group same-frequency elements on the same Canvas&lt;/li&gt;
&lt;li&gt;Minimize the number of elements on frequently-updated Canvases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Trade-offs to consider:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More Canvases add management complexity&lt;/li&gt;
&lt;li&gt;Elements on different Canvases can't batch with each other (potential DrawCall increase)&lt;/li&gt;
&lt;li&gt;Each Canvas has small fixed overhead&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice, when BuildBatch is a real bottleneck, the CPU savings almost always justify the trade-offs.&lt;/p&gt;

</description>
      <category>ui</category>
      <category>performance</category>
      <category>unity3d</category>
      <category>development</category>
    </item>
    <item>
      <title>UGUI Overdraw Optimization: Tight Meshes, Transparent Culling, and 9-Slicing</title>
      <dc:creator>GameOptim</dc:creator>
      <pubDate>Tue, 15 Sep 2026 07:11:38 +0000</pubDate>
      <link>https://dev.to/gameoptim/ugui-overdraw-optimization-tight-meshes-transparent-culling-and-9-slicing-12jb</link>
      <guid>https://dev.to/gameoptim/ugui-overdraw-optimization-tight-meshes-transparent-culling-and-9-slicing-12jb</guid>
      <description>&lt;h2&gt;
  
  
  Problem / Scenario
&lt;/h2&gt;

&lt;p&gt;Overdraw—pixels drawn multiple times by overlapping UI elements—is a major source of GPU cost in UGUI, especially on mobile devices. For a weapon UI panel with circular backgrounds, item frames, and hidden selection states, the Overdraw was visibly high when viewed in Unity's Overdraw mode. The goal: reduce Overdraw without changing any visual output.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Observed
&lt;/h2&gt;

&lt;p&gt;Using Scene view's &lt;strong&gt;Overdraw&lt;/strong&gt; shading mode, we identified three problem areas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Background circles&lt;/strong&gt; — very bright, indicating high Overdraw from full-quad meshes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Selected-state backgrounds&lt;/strong&gt; — elements hidden via Alpha=0 still contributing to Overdraw&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weapon item frames&lt;/strong&gt; — hollow frames drawing full rectangles of mostly transparent pixels&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How to Analyze It
&lt;/h2&gt;

&lt;p&gt;Overdraw mode color intensity correlates with the number of times pixels are overdrawn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dark/black: no Overdraw (drawn once)&lt;/li&gt;
&lt;li&gt;Bright colors: high Overdraw (drawn many times)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For each bright area, we asked: is all this drawing necessary? In all three cases, the answer was no.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimization Techniques
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Tight Mesh for Sprites with Transparency
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Circular and irregular sprites use rectangular (quad) meshes by default. The transparent corners and edges of the quad are still rasterized, wasting GPU fill rate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Use Unity's Tight mesh generation.&lt;/p&gt;

&lt;p&gt;Steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select sprite asset → Inspector → &lt;strong&gt;Mesh Type: Tight&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;On Image component → &lt;strong&gt;Use Sprite Mesh: enabled&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Adjust &lt;strong&gt;Extrude Edges&lt;/strong&gt; parameter to control mesh polygon count&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt; Unity generates a polygon mesh that tightly wraps the visible alpha contour of the sprite. Fully transparent areas are excluded from the mesh entirely, so they never reach the rasterizer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Polygon count tuning:&lt;/strong&gt; The default Tight mesh can be quite dense (many vertices for smooth contours). Reducing &lt;strong&gt;Extrude Edges&lt;/strong&gt; lowers vertex count while maintaining visual quality. For our circular sprites, a value of 6 produced clean results with minimal polygons.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Cull Transparent Mesh for Alpha=0 Elements
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; UI elements hidden by setting &lt;code&gt;color.a = 0&lt;/code&gt; are still submitted for rendering. The mesh is built, the draw call is issued, and the fragment shader runs for every pixel—all producing nothing visible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Enable &lt;strong&gt;Cull Transparent Mesh&lt;/strong&gt; on the Canvas Renderer component.&lt;/p&gt;

&lt;p&gt;When this option is enabled and the element's final alpha is 0, Unity culls the entire element from rendering. No vertices, no draw call, no Overdraw.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Limitations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only works when alpha is exactly 0&lt;/li&gt;
&lt;li&gt;Fading animations (alpha from 1 to 0) still render during the transition&lt;/li&gt;
&lt;li&gt;Only the final element alpha matters, not parent canvas group alpha&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. 9-Slicing for Hollow Frame Sprites
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Frame/border sprites have large transparent centers. The default mesh covers the full rectangle, including all that empty space.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Use 9-slicing with Fill Center disabled.&lt;/p&gt;

&lt;p&gt;Steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the sprite in Sprite Editor&lt;/li&gt;
&lt;li&gt;Drag the 9-slice border handles inward to match the inner edge of the frame&lt;/li&gt;
&lt;li&gt;Apply changes&lt;/li&gt;
&lt;li&gt;On Image component → &lt;strong&gt;Image Type: Sliced&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Disable &lt;strong&gt;Fill Center&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt; 9-slicing divides the sprite into 9 regions. With Fill Center disabled, the center region produces no geometry at all—only the 4 corners and 4 edges generate vertices. The result is a frame shape with no center fill.&lt;/p&gt;

&lt;h2&gt;
  
  
  Root Cause
&lt;/h2&gt;

&lt;p&gt;The common thread across all three techniques: &lt;strong&gt;UGUI draws more pixels than necessary&lt;/strong&gt; because it defaults to simple rectangular meshes and renders even fully transparent content. Most Overdraw in UGUI isn't from UI elements overlapping each other—it's from individual elements drawing invisible pixels.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaway
&lt;/h2&gt;

&lt;p&gt;Overdraw optimization in UGUI mostly comes down to "don't draw what the player can't see." Three techniques cover the vast majority of cases:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Technique&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;th&gt;Effort&lt;/th&gt;
&lt;th&gt;Impact&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tight Mesh&lt;/td&gt;
&lt;td&gt;Circular/irregular sprites&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cull Transparent Mesh&lt;/td&gt;
&lt;td&gt;Elements hidden via Alpha=0&lt;/td&gt;
&lt;td&gt;Very low&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9-Slicing (no Fill Center)&lt;/td&gt;
&lt;td&gt;Frames, borders, buttons&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All three preserve visual quality while reducing GPU fill rate usage. They should be standard practice in any UGUI project targeting mobile devices.&lt;/p&gt;

</description>
      <category>ui</category>
      <category>performance</category>
      <category>unity3d</category>
      <category>overdraw</category>
    </item>
  </channel>
</rss>
