public string Execute(string[] args) { NetVips.CacheSetMax(0); Image b; using (var a = Image.NewFromMemory(Enumerable.Repeat((byte)255, 200).ToArray(), 20, 10, 1, "uchar")) { b = a / 2; } // g_object_unref Console.WriteLine($"Reference count b: {b.RefCount}"); var average = b.Avg(); Console.WriteLine($"Before GC: {average}"); GC.Collect(); GC.WaitForPendingFinalizers(); average = b.Avg(); Console.WriteLine($"After GC: {average}"); return("All done!"); }
/// <summary> /// Load from memory buffer 10000 times. /// /// It runs in a fairly steady 60MB of ram for me. Watching the output, you see /// stuff like: /// /// memory processing <NetVips.Image 4120x2747 uchar, 3 bands, srgb> /// 24 vips objects known to net-vips /// memory processing <NetVips.Image 4120x2747 uchar, 3 bands, srgb> /// 21 vips objects known to net-vips /// memory processing <NetVips.Image 4120x2747 uchar, 3 bands, srgb> /// 23 vips objects known to net-vips /// memory processing <NetVips.Image 4120x2747 uchar, 3 bands, srgb> /// 16 vips objects known to net-vips /// memory processing <NetVips.Image 4120x2747 uchar, 3 bands, srgb> /// 7 vips objects known to net-vips /// memory processing <NetVips.Image 4120x2747 uchar, 3 bands, srgb> /// 7 vips objects known to net-vips /// memory processing <NetVips.Image 4120x2747 uchar, 3 bands, srgb> /// 9 vips objects known to net-vips /// memory processing <NetVips.Image 4120x2747 uchar, 3 bands, srgb> /// 4 vips objects known to net-vips /// memory processing <NetVips.Image 4120x2747 uchar, 3 bands, srgb> /// /// So when around 25 vips objects are alive, the C# gc runs and they all get /// flushed. /// /// If you want it to run in less ram than that, you'll need to expose the GC and /// trigger it manually every so often. /// </summary> /// <param name="args">Command-line arguments.</param> /// <returns>Result.</returns> public string Execute(string[] args) { NetVips.LeakSet(true); NetVips.CacheSetMax(0); var imageBytes = File.ReadAllBytes(Filename); for (var i = 0; i < 10000; i++) { using var img = Image.NewFromBuffer(imageBytes); Console.WriteLine($"memory processing {img}"); // uncomment this line together with the `NObjects` variable in GObject // Console.WriteLine($"{GObject.NObjects} vips objects known to net-vips"); } return("All done!"); }
public string Execute(string[] args) { NetVips.CacheSetMax(0); using var fileStream = File.OpenRead(Filename); using var image = Image.NewFromStream(fileStream); for (var i = 0; i < 1000; i++) { using var crop = image.Crop(0, 0, 256, 256); var _ = crop.Avg(); Console.WriteLine($"reference count: {image.RefCount}"); // RefCount should not increase (i.e. operation should be freed) Debug.Assert(image.RefCount == 2u); } var count = 0; var locker = new object(); Parallel.For(0, 1000, new ParallelOptions { MaxDegreeOfParallelism = NetVips.ConcurrencyGet() }, i => { Interlocked.Increment(ref count); using var crop = image.Crop(0, 0, 256, 256); lock (locker) { var _ = crop.Avg(); Console.WriteLine($"reference count: {image.RefCount} with {count} active threads"); // RefCount -1 must be lower than or equal to the number of active threads Debug.Assert(image.RefCount - 1 <= (uint)count); } Interlocked.Decrement(ref count); }); return("All done!"); }