Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory leak #48

Closed
paulushub opened this issue Nov 29, 2017 · 10 comments
Closed

Memory leak #48

paulushub opened this issue Nov 29, 2017 · 10 comments
Labels

Comments

@paulushub
Copy link
Contributor

paulushub commented Nov 29, 2017

I think, there is a memory leak when I use FileSvgReader.Read method.

I have downloaded the SharpVectors converter application, and I have used the normal file converter.
The application takes ~30Mb-es after start. My svg file is about 300kb and when I click the "convert" button, the memory usage starts to increase.
When it is ready the application memory usage is ~60Mb (!!!) and do not decrease.

I have tried it with a 11Mb svg file, and the memory usage is ~700Mb after the successful convert.

It is the same situation in my applicaion which uses only the FileSvgReader.Read method.

Please check this situation!

Thank you!
Best Reagards,
Gergely

Attachments

Csongrad_megye.svg

This work item was migrated from CodePlex

CodePlex work item ID: '1889'
Vote count: '1'

@paulushub
Copy link
Contributor Author

[Spuriga@2015/07/08]
Hello!

Could you help me, when this problem will be checked?

Thanks in advance!

@paulushub
Copy link
Contributor Author

[SelormeyPaul@2015/07/09]
For a library, there is little to do. If you finish with the conversion in your application, try the following to force the clean by the .NET runtime:

     GC.Collect();
     GC.WaitForPendingFinalizers();
     GC.Collect();

@paulushub
Copy link
Contributor Author

[UnknownUser@2015/07/13]

@paulushub
Copy link
Contributor Author

[Spuriga@2015/07/13]
Hello!

I have tried it, but not success! :(

When my code is starting it use 3Mb-s of memory, and when it is finished it use 45Mb-s. I have tried it in a cycle, doing the same 10 times, and the memory increased to 450Mb-s.

In the attachement, you can find the "Csongrad_megye.svg" file. Of course I have many map file with the same situation, not this is the only one.

static void Main(string[] args)
{
    byte[] svgByteArray = File.ReadAllBytes(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Csongrad_megye.svg"));

    DrawingGroup dg;
    using (var stream = new MemoryStream(svgByteArray))
    {
        using (FileSvgReader fr = new FileSvgReader(null))
        {
            dg = fr.Read(stream);
        }
    }

    dg = null;

    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();

    Console.WriteLine("Ready!");
    Console.ReadLine();
}

@paulushub
Copy link
Contributor Author

[SelormeyPaul@2015/07/13]
Without testing, I could see the code you submitted is useless. How are you expecting the svgByteArray you created to go away? Why do you even need the byte array if you can directly read the file?

static void Main(string[] args)
{
    string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Csongrad_megye.svg");

    DrawingGroup dg;
    using (FileSvgReader fr = new FileSvgReader(null))
    {
       dg = fr.Read(filePath);
    }

    dg = null;

    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();

    Console.WriteLine("Ready!");
    Console.ReadLine();
}

@paulushub
Copy link
Contributor Author

[Spuriga@2015/07/13]
In my application the file comes out from a WCF channel in byte array. But ok, there is no problem, with your code the situation is the same. :(

@paulushub
Copy link
Contributor Author

[SelormeyPaul@2015/07/16]
Hello,
There is no memory leak and nothing to fix. You simply do not control .NET memory management and that will not change. If you want a C/C++ release of memory, the closest you can get is run your conversions in a separate domain and if you done, you release the domain to release the resources associated with that domain.

NOTE: I am, therefore, closing this issue.

using System;
using System.Windows.Media;
using System.IO;
using SharpVectors.Converters;
using System.Reflection;

namespace TestConsole
{
    class Program
    {
        // Because this class is derived from MarshalByRefObject, a proxy  
        // to a MarshalByRefSvgConverter object can be returned across an AppDomain  
        // boundary. 
        public sealed class MarshalByRefSvgConverter : MarshalByRefObject
        {
            //  Call this method via a proxy. 
            public void RunTest(string filePath)
            {
                DrawingGroup dg;
                using (FileSvgReader fr = new FileSvgReader(null))
                {
                    dg = fr.Read(filePath);
                }

                dg = null;

                Console.WriteLine("Stage 2: " + GC.GetTotalMemory(true));
            }
        }


        private static void RunTest(String filePath)
        {
            DrawingGroup dg;
            using (FileSvgReader fr = new FileSvgReader(null))
            {
                dg = fr.Read(filePath);
            }         
            dg = null;

            Console.WriteLine("Stage 2: " + GC.GetTotalMemory(true));

            GC.Collect(0, GCCollectionMode.Forced);
            GC.WaitForPendingFinalizers();
            GC.Collect(0, GCCollectionMode.Forced);
        }

        static void Main(string[] args)
        {
            String filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Csongrad_megye.svg");
            Console.WriteLine("Stage 1: " + GC.GetTotalMemory(true));

            // Program.RunTest(filePath);

            // Construct and initialize settings for a second AppDomain.
            AppDomainSetup domainSetup = new AppDomainSetup();
            domainSetup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;

            domainSetup.DisallowBindingRedirects = false;
            domainSetup.DisallowCodeDownload = true;
            domainSetup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;

            // Create the second AppDomain.
            AppDomain svgDomain = AppDomain.CreateDomain("SVG-Converter", null, domainSetup);

            // Get and display the full name of the EXE assembly. 
            string exeAssembly = Assembly.GetEntryAssembly().FullName;
            // Create an instance of MarshalByRefSvgConverter in the second AppDomain.  
            // A proxy to the object is returned.
            MarshalByRefSvgConverter svgProxy = (MarshalByRefSvgConverter)svgDomain.CreateInstanceAndUnwrap(
                    exeAssembly, typeof(MarshalByRefSvgConverter).FullName);

            // Call a method on the object via the proxy, passing the filename
            for (int i = 0; i < 10; i++)
            {
                svgProxy.RunTest(filePath);
            } 

            // Unload the second AppDomain. This deletes its object and  
            // invalidates the proxy object.
            AppDomain.Unload(svgDomain);

            Console.WriteLine("Stage 3: " + GC.GetTotalMemory(true));

            Console.WriteLine("Ready!");
            Console.ReadLine();
        }
    }
}

@paulushub
Copy link
Contributor Author

[Spuriga@2015/07/20]
Thanks, it work preatty well!

@paulushub
Copy link
Contributor Author

[UnknownUser@2016/10/14]

@paulushub
Copy link
Contributor Author

Issue closed by SelormeyPaul with comment
Simple memory management will resolve the issue.

Reason closed
Fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant