Phreak87 / LeptonicaSharp

Full featured wrapper for leptonica 1.77.0
Other
8 stars 5 forks source link

Dispose of Object with Marshalling #58

Closed fdncred closed 5 years ago

fdncred commented 5 years ago

Generally speaking there could be a problem with the way everything is marshalled.

Take this Dispose of PixColormap for example.

public void Dispose()
{
    foreach (KeyValuePair<string, object> Entry in Caching) {
        var disp = Entry.Value as IDisposable;
        if (disp != null) { disp.Dispose(); }
    }

    Caching.Clear();
    Caching = null;
    Marshal.DestroyStructure(Pointer, typeof(Marshal_PixColormap));
    Array.Clear(this.Array_Bytes, 0, Array_Bytes.Length);
    this.Array_Bytes = null;
    Array.Clear(Array_Color, 0, Array_Color.Length);
    GC.Collect();
    Pointer = IntPtr.Zero;
    System.GC.SuppressFinalize(this);
}

The GC.Collect() is just for testing but the Array.Clear() should clear the array to all 0's. It does not because every time Array_Bytes is accessed it re-marshals everything and re-establishes the Array_Bytes. I had to rewrite Array_Bytes as this below because there is no setter so one can't set it to null.

private byte[] array_bytes;
public byte[] Array_Bytes
{
    get {
        if ((Values == null))
        { return null; }

            array_bytes = new byte[(n * 4)];
        Marshal.Copy(array, array_bytes, 0, array_bytes.Length);
        return array_bytes;
    }
    set { array_bytes = value; }
}

As a comparison, debug this code and you'll see the difference.

var ta = new byte[1000];
for (int i = 0; i < ta.Length; i++)
{
    ta[i] = (byte)(i + 100);
}
Array.Clear(ta, 0, ta.Length);
ta = null;
GC.Collect();

If there's no way to free memory this library will have many problems.

Phreak87 commented 5 years ago

i know. two ways to fix: Implement Set and marshal back to Ptr use the Leptonica Function pixSetData

fdncred commented 5 years ago

I'll wait to see some code because I'm not sure how either of those will work when the getter always marshals the data unless the pointer is null.

Phreak87 commented 5 years ago

i tested with a colormap only. and this works. if this is a colormap in a pix it should not be modified directly. The right way to change the colormap (or clear) is to call pixcmapClear or pixCmapDestroy which sets the byref pointer to null and clears the array.

Phreak87 commented 5 years ago

i tested with pix too and if the pixpointer is null theres no recreation. so i think this could be closed.

fdncred commented 5 years ago

So, how do you dispose of Array_Bytes? Array.Clear() doesn't work because you reallocate every time you mention Array_Bytes.

Phreak87 commented 5 years ago

You Reallocate if you look at. on pix dispose all classes and cache are cleaned. after this the ptr is set to null and the cache will dont be filled again because of this.

https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail Virenfrei. www.avast.com https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>

Am Di., 18. Dez. 2018 um 22:07 Uhr schrieb Darren Schroeder < notifications@github.com>:

So, how do you dispose of Array_Bytes? Array.Clear() doesn't work because you reallocate every time you mention Array_Bytes.

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/Phreak87/LeptonicaSharp/issues/58#issuecomment-448370796, or mute the thread https://github.com/notifications/unsubscribe-auth/AHvBIBhiPzdXWw1yGvKL8K9I5wnyrn-iks5u6VkQgaJpZM4ZOJVK .