SkiaSharp icon indicating copy to clipboard operation
SkiaSharp copied to clipboard

[BUG] [iOS] SKGLView Memory Leak compared to SKCanvasView

Open IainS1986 opened this issue 4 years ago • 8 comments

Description

I've been investigating a memory issues i've been seeing when using SKGLView compared to SKCanvasView.

I'm using SkiaScene to handle touch manipulation but I'm fairly confident that isn't the issue.

To better test, I setup my project on iOS with a CADisplayLink to continuously trigger a SetNeedsDisplay on the Skia view so a new render will occur (I found the memory leak like this when I was doing a simple animation using CADisplayLink and left the animation running, its also possible to trigger this by continuously touching the screen triggering a redraw, but obviously thats much more effort to test!).

My skia drawing is fairly complex but at the root of it, the current example is basically drawing approximately 30 DrawLine calls and 30 DrawCircle calls every render.

I'm comparing the exact same code, with the only difference being one uses SKGLView and one uses SKCanvasView. I hook up to the PaintSurface events and the canvas from the surface is passed through the rendering, from what I can tell the reference to the canvas is never stored off anywhere within my logic (or SkiaScene).

With SKGLView, after about 1 minute the app completely freezes. No crash or application output is displayed or recieved. Looking at the console for the device the following lines print out...

IOReturn IOGPUDevice::new_resource(IOGPUNewResourceArgs *, struct IOGPUNewResourceReturnData *, IOByteCount, uint32_t *): PID 40079 likely leaking IOGPUResource (count=46000)
IOReturn IOGPUDevice::new_resource(IOGPUNewResourceArgs *, struct IOGPUNewResourceReturnData *, IOByteCount, uint32_t *): PID 40079 likely leaking IOGPUResource (count=47000)
IOReturn IOGPUDevice::new_resource(IOGPUNewResourceArgs *, struct IOGPUNewResourceReturnData *, IOByteCount, uint32_t *): PID 40079 likely leaking IOGPUResource (count=48000)
IOReturn IOGPUDevice::new_resource(IOGPUNewResourceArgs *, struct IOGPUNewResourceReturnData *, IOByteCount, uint32_t *): PID 40079 likely leaking IOGPUResource (count=49000)

This continues until count=60000 and then it freezes (always increasing in 1000 increments and freezing at 60000).

When I run the exact same code with SKCanvasView it can run forever (I've had the app running for 2hr+ on my desk and never had it freeze).

Below you can see the Xamarin profiler outputs. The first is the SKGLView and you can see it shoots up to a working set of around 500mb, then decreases and during this time the errors start printing out, and eventually it freezes (flatlines in the profiler).

The second is SKCanvasView, you can see my memory increases to a point, then when the continous rendering update occurs the memory basically hovers flat around 185mb (with a slight creep up but I suspect that isn't Skia related).

I've checked the Handle on the e.Surface.Canvas in the PaintSurface event when using the SKGLView and it always seems to be the same, so I'm getting the same canvas object through in the PaintSurface event (I think).

I'm calling Flush on the canvas after rendering.

Any thoughts?

Basic Information

  • Version with issue: 2.80.2
  • IDE: Visual Studio for Mac
  • Platform Target Frameworks:
    • iOS: Min Deploy Target of 12.0
  • Target Devices:
    • iPhone 6s
    • iPad Mini 4
Detailed IDE/OS information (click to expand)

=== Visual Studio Enterprise 2019 for Mac ===

Version 8.9.4 (build 25)
Installation UUID: 088507f4-3001-4ca4-9722-69b7ab1ca6e1
	GTK+ 2.24.23 (Raleigh theme)
	Xamarin.Mac 6.18.0.23 (d16-6 / 088c73638)

	Package version: 612000125

=== Mono Framework MDK ===

Runtime:
	Mono 6.12.0.125 (2020-02/8c552e98bd6) (64-bit)
	Package version: 612000125

=== Roslyn (Language Service) ===

3.9.0-6.21152.10+c10f884b30737542ddd84ca889a4aad9281ce210

=== NuGet ===

Version: 5.8.0.6860

=== .NET Core SDK ===

SDK: /usr/local/share/dotnet/sdk/5.0.201/Sdks
SDK Versions:
	5.0.201
	5.0.103
	5.0.101
	5.0.100
	3.1.407
	3.1.406
	3.1.404
	3.1.403
	3.1.402
	3.1.401
	3.1.302
	3.1.301
	3.1.300
	3.1.202
	3.1.200
	3.1.102
MSBuild SDKs: /Applications/Visual Studio.app/Contents/Resources/lib/monodevelop/bin/MSBuild/Current/bin/Sdks

=== .NET Core Runtime ===

Runtime: /usr/local/share/dotnet/dotnet
Runtime Versions:
	5.0.4
	5.0.3
	5.0.1
	5.0.0
	3.1.13
	3.1.12
	3.1.10
	3.1.9
	3.1.8
	3.1.7
	3.1.6
	3.1.5
	3.1.4
	3.1.2
	2.1.23
	2.1.22
	2.1.21
	2.1.20
	2.1.19
	2.1.18
	2.1.17
	2.1.16

=== .NET Core 3.1 SDK ===

SDK: 3.1.407

=== Xamarin.Profiler ===

Version: 1.6.13.11
Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler

=== Updater ===

Version: 11

=== Xamarin Designer ===

Version: 16.9.0.316
Hash: 2241b204a
Branch: tags/vsm-rel/d16.9-4540908
Build date: 2021-03-10 21:18:10 UTC

=== Apple Developer Tools ===

Xcode 12.4 (17801)
Build 12D4e

=== Xamarin.Mac ===

Version: 7.8.2.5 (Visual Studio Enterprise)
Hash: 3836759d4
Branch: d16-9
Build date: 2021-02-10 17:56:43-0500

=== Xamarin.iOS ===

Version: 14.14.2.5 (Visual Studio Enterprise)
Hash: 3836759d4
Branch: d16-9
Build date: 2021-02-10 17:56:44-0500

=== Xamarin.Android ===

Version: 11.2.2.1 (Visual Studio Enterprise)
Commit: xamarin-android/d16-9/877f572
Android SDK: /Users/iainstanford/Library/Developer/Xamarin/android-sdk-macosx
	Supported Android versions:
		5.1 (API level 22)
		6.0 (API level 23)
		7.1 (API level 25)
		8.1 (API level 27)

SDK Tools Version: 26.1.1
SDK Platform Tools Version: 31.0.0
SDK Build Tools Version: 30.0.3

Build Information: 
Mono: 5e9cb6d
Java.Interop: xamarin/java.interop/d16-9@54f8c24
ProGuard: Guardsquare/proguard/v7.0.1@912d149
SQLite: xamarin/sqlite/3.34.1@daff8f4
Xamarin.Android Tools: xamarin/xamarin-android-tools/d16-9@d210f11

=== Microsoft OpenJDK for Mobile ===

Java SDK: /Users/iainstanford/Library/Developer/Xamarin/jdk/microsoft_dist_openjdk_1.8.0.25
1.8.0-25
Android Designer EPL code available here:
https://github.com/xamarin/AndroidDesigner.EPL

=== Android SDK Manager ===

Version: 16.9.0.22
Hash: a391de2
Branch: remotes/origin/d16-9~2
Build date: 2021-03-24 08:30:26 UTC

=== Android Device Manager ===

Version: 16.9.0.17
Hash: fc2b3db
Branch: remotes/origin/dev/jmt/d16-9bump~1
Build date: 2021-03-24 08:30:44 UTC

=== Build Information ===

Release ID: 809040025
Git revision: 5d0f80a4343884101c6c7869bc61d5101cf30052
Build date: 2021-03-25 08:43:13-04
Build branch: release-8.9
Xamarin extensions: 5d0f80a4343884101c6c7869bc61d5101cf30052

=== Operating System ===

Mac OS X 10.15.7
Darwin 19.6.0 Darwin Kernel Version 19.6.0
    Thu Oct 29 22:56:45 PDT 2020
    root:xnu-6153.141.2.2~1/RELEASE_X86_64 x86_64

Screenshots

SKGLView Memory Usage: Screenshot 2021-04-07 at 08 50 51

SKCanvasView Memory Usage: Screenshot 2021-04-07 at 09 09 21

IainS1986 avatar Apr 07 '21 08:04 IainS1986

This issue is possibly related to my issue as I also use the hardware acceleration. The memory usage over time is comparable. https://github.com/mono/SkiaSharp/issues/1680

radev8 avatar Apr 08 '21 06:04 radev8

@radev8 I'll double check but I'm pretty certain I see the exact same rate of memory increase even with no SKPath usage

But certainly sounds in a similar area, and interesting yours is UWP while this is iOS. Both ARM based GPUs maybe?

IainS1986 avatar Apr 08 '21 07:04 IainS1986

@IainS1986 As you could see, we now have the same problems as you: When there are many redraws in short time then the app crashes with the same GPU error.

Do you find a solution for this?

charlenni avatar Sep 07 '21 07:09 charlenni

@charlenni yes - don't use SKGLView on iOS.

IainS1986 avatar Sep 07 '21 07:09 IainS1986

😂

Thank you for your fast answer.

Do you use SKPath for your drawings? Could it be, that there are resources created that aren't released before the next drawing?

charlenni avatar Sep 07 '21 08:09 charlenni

I assume here, that you use SKPath.

I assume, that there are problems with releasing the resources. Perhaps Skia uploads a path to the GPU for drawing, because it thinks, that the path is drawn again and again. But in some cases, if you create the SKPath every time new before drawing it, the release of the resources on GPU is not fast enough.

Did you try to release them by explicitly deleting SKPath after drawing the path?

charlenni avatar Sep 07 '21 09:09 charlenni

I use SKPath and I completely reuse the same paths in every redraw (Rewinding the same path to then reuse it). Before this I also released the SKPaths - both approaches still crashed.

However - its been a long time (April) - but I believe I could reproduce the memory issue without any SKPath calls too.

I don't think its SKPath specific. I think you could have a blank SKGLView and redraw every frame and get the same error.

IainS1986 avatar Sep 07 '21 09:09 IainS1986

This defect would be a HUGE issue for us. Without the GPU-based SKGLView, we will be unable to make use of Custom Shaders, right? We NEED Custom Skia Shaders to create the needed effects, plus we need/want the performance boost. From what I can tell, this has never been fixed, correct?

BUT, I ran a test myself, where all I did was this:

  1. Clear(Green)
  2. DrawBitmap (full sized, 1000x2000 pixels approx)
  3. DrawPath Polygon 50 points. Each time I create a new Path (but using the same SKPoint[50] array), and do NOT dispose of the previous one (was trying to induce a crash that I could then see if Dispose() fixed it -- but for me, not calling Dispose() even works).

It Runs continuously at 50 FPS. No hiccups.

It's been running now for 15 minutes (900 seconds x 50 FPS = 45,000 frames rendered), and no crash yet. Performance hasn't slowed. I will let it run all night, and see if it's still running 8 hrs from now, and will update this comment.

EDIT: Yep, it ran for 8.5 hrs -- full speed, no slow downs, no crashes. 50 FPS, recreating a 50 pt Polygon Path every single frame.

I don't have a profiler here to show me the memory usage on my iPad.

I'm using Skia 2.88.6, on iOS 16.7, iPad Mini 4.

So for me, it appears it might be fixed? Or maybe my test case simply doesn't cause the defect for some reason.

najak3d avatar Oct 06 '23 09:10 najak3d