Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. GC in Services

GC in Services

Scheduled Pinned Locked Moved C#
csharpdata-structuresperformancehelpquestion
15 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S solidstore

    I have a strange problem related to ever rising memory in the GC heaps. When I run my service, memory is continually allocated during a test cycle. However if I simply change the services startup routine to instead just wait showing a messagebox (instead of adding the service) and let the other threads carry on their work I get a nice zig-zag line as expected in perfmon showing #Bytes in all Heaps which always stays under #Total committed Bytes. The graph for the service version just increases upward for both counters. What could be happening? I understand that the GC only collects memory if it has to, and is only does this during further allocations but I want to prevent my service claim more resources than is needs to run preventing other NON .NET application being starved of RAM.

    L Offline
    L Offline
    leppie
    wrote on last edited by
    #2

    solidstore wrote: I understand that the GC only collects memory if it has to, and is only does this during further allocations but I want to prevent my service claim more resources than is needs to run preventing other NON .NET application being starved of RAM. What memory intense objects are you creating? Perhaps implementing them as a static object will not require it to be created everytime, and does it need to be created for every call or does the object prefer to stay "persistant" across web service calls? You will have to supply some more info if you want someone to give you a better answer. :)

    leppie::AllocCPArticle(Generic DFA State Machine for .NET);

    S 1 Reply Last reply
    0
    • S solidstore

      I have a strange problem related to ever rising memory in the GC heaps. When I run my service, memory is continually allocated during a test cycle. However if I simply change the services startup routine to instead just wait showing a messagebox (instead of adding the service) and let the other threads carry on their work I get a nice zig-zag line as expected in perfmon showing #Bytes in all Heaps which always stays under #Total committed Bytes. The graph for the service version just increases upward for both counters. What could be happening? I understand that the GC only collects memory if it has to, and is only does this during further allocations but I want to prevent my service claim more resources than is needs to run preventing other NON .NET application being starved of RAM.

      D Offline
      D Offline
      Daniel Turini
      wrote on last edited by
      #3

      Are you using COM objects in your service, like ADO recordsets? They can be a big source for memory leaks, because all the GC can see is the managed allocated memory, which is small, basically a pointer to a small wrapper. But, on the side of the COM object, it may be taking several MB of RAM. So, to assure a COM object is correctly garbage collected, you need to call System.Runtime.Interop.Marshal.ReleaseComObject on a loop until it returns 0. Another common source for memory leaks under a GC environment is forgetting to call Dispose on the IDisposable objects. My latest article: GBVB - Converting VB.NET code to C#

      S 1 Reply Last reply
      0
      • S solidstore

        I have a strange problem related to ever rising memory in the GC heaps. When I run my service, memory is continually allocated during a test cycle. However if I simply change the services startup routine to instead just wait showing a messagebox (instead of adding the service) and let the other threads carry on their work I get a nice zig-zag line as expected in perfmon showing #Bytes in all Heaps which always stays under #Total committed Bytes. The graph for the service version just increases upward for both counters. What could be happening? I understand that the GC only collects memory if it has to, and is only does this during further allocations but I want to prevent my service claim more resources than is needs to run preventing other NON .NET application being starved of RAM.

        S Offline
        S Offline
        solidstore
        wrote on last edited by
        #4

        When our code is running as a normal C# process, garbage collect can be seen working using perfmon during a test. Running the same code but as a service, garbage collection does not appear to kick in? However when attaching the Memory Profiler the service returns to expected garbage collection as viewed from perfmon. What could cause my code running as a process (and profiled service) to have a nice shallow zig-zag perfmon trace of #bytes in heap. Yet when its run as a service the #bytes in heap rises very steeply indeed and no sign of the garbage collector's zig-zag? The code is fully managed and I'm not using any COM objects. I am exposing object within my assembly to COM and via Remoting

        1 Reply Last reply
        0
        • L leppie

          solidstore wrote: I understand that the GC only collects memory if it has to, and is only does this during further allocations but I want to prevent my service claim more resources than is needs to run preventing other NON .NET application being starved of RAM. What memory intense objects are you creating? Perhaps implementing them as a static object will not require it to be created everytime, and does it need to be created for every call or does the object prefer to stay "persistant" across web service calls? You will have to supply some more info if you want someone to give you a better answer. :)

          leppie::AllocCPArticle(Generic DFA State Machine for .NET);

          S Offline
          S Offline
          solidstore
          wrote on last edited by
          #5

          Basically I have a Windows Service which is hosting some Remotable objects. These objects are also registered with COM. Our test client in an ASP code which creates the COM objects. This activate the real .NET object inside my C# service. Everything work fine, except that memory allocs continue endlessly. In desperation I changed the service to run as a standard process whilst I was debugging. Now memory is being correctly garbage collected. I'm using the perfmon counter to view the zig-zag profile. Memory only increase when the code is run as a Service. I just have to replace the ServiceBase.Run method call with a long Sleep. To make my test run behave VERY differently. The objects I'm creating for each test call are very small & stateless. They return a small string ("foo") from they only method call. The ASP code sets the object to Nothing after the call. I'm assuming releasing the COM object, releases the CCW, which release the remote server object.

          D 1 Reply Last reply
          0
          • D Daniel Turini

            Are you using COM objects in your service, like ADO recordsets? They can be a big source for memory leaks, because all the GC can see is the managed allocated memory, which is small, basically a pointer to a small wrapper. But, on the side of the COM object, it may be taking several MB of RAM. So, to assure a COM object is correctly garbage collected, you need to call System.Runtime.Interop.Marshal.ReleaseComObject on a loop until it returns 0. Another common source for memory leaks under a GC environment is forgetting to call Dispose on the IDisposable objects. My latest article: GBVB - Converting VB.NET code to C#

            S Offline
            S Offline
            solidstore
            wrote on last edited by
            #6

            see reply to leppie above - many thanks

            1 Reply Last reply
            0
            • S solidstore

              Basically I have a Windows Service which is hosting some Remotable objects. These objects are also registered with COM. Our test client in an ASP code which creates the COM objects. This activate the real .NET object inside my C# service. Everything work fine, except that memory allocs continue endlessly. In desperation I changed the service to run as a standard process whilst I was debugging. Now memory is being correctly garbage collected. I'm using the perfmon counter to view the zig-zag profile. Memory only increase when the code is run as a Service. I just have to replace the ServiceBase.Run method call with a long Sleep. To make my test run behave VERY differently. The objects I'm creating for each test call are very small & stateless. They return a small string ("foo") from they only method call. The ASP code sets the object to Nothing after the call. I'm assuming releasing the COM object, releases the CCW, which release the remote server object.

              D Offline
              D Offline
              Daniel Turini
              wrote on last edited by
              #7

              solidstore wrote: Memory only increase when the code is run as a Service. I just have to replace the ServiceBase.Run method call with a long Sleep. To make my test run behave VERY differently. The objects I'm creating for each test call are very small & stateless. They return a small string ("foo") from they only method call. From what you're saying, it seems to be a bug in the .NET framework. Your ASP page hasn't changed, only the server is changing, but the components are no being released anymore. Are they MarshalByValue or MarshalByRef objects? Depending on what you're doing, as a workaround, I suggest you to derive your classes from ServicedComponent and run them from inside a COM+ application, and export the application proxy, so the ASP page could call your components. I use it all the time and it's very stable. My latest article: GBVB - Converting VB.NET code to C#

              S 2 Replies Last reply
              0
              • D Daniel Turini

                solidstore wrote: Memory only increase when the code is run as a Service. I just have to replace the ServiceBase.Run method call with a long Sleep. To make my test run behave VERY differently. The objects I'm creating for each test call are very small & stateless. They return a small string ("foo") from they only method call. From what you're saying, it seems to be a bug in the .NET framework. Your ASP page hasn't changed, only the server is changing, but the components are no being released anymore. Are they MarshalByValue or MarshalByRef objects? Depending on what you're doing, as a workaround, I suggest you to derive your classes from ServicedComponent and run them from inside a COM+ application, and export the application proxy, so the ASP page could call your components. I use it all the time and it's very stable. My latest article: GBVB - Converting VB.NET code to C#

                S Offline
                S Offline
                solidstore
                wrote on last edited by
                #8

                My remote objects derive from MarshalByRefObject and their custom COM interface. I read in a newsgroup somewhere that if you derive from this class you must call System.Runtime.Remoting.RemotingServices.Disconnect. But from where? How simple is hosting inside COM+? I'm meant to ship this week! Could anyone else confirm this is a bug in .NET? You only need a small application to test this I guess.

                D 1 Reply Last reply
                0
                • D Daniel Turini

                  solidstore wrote: Memory only increase when the code is run as a Service. I just have to replace the ServiceBase.Run method call with a long Sleep. To make my test run behave VERY differently. The objects I'm creating for each test call are very small & stateless. They return a small string ("foo") from they only method call. From what you're saying, it seems to be a bug in the .NET framework. Your ASP page hasn't changed, only the server is changing, but the components are no being released anymore. Are they MarshalByValue or MarshalByRef objects? Depending on what you're doing, as a workaround, I suggest you to derive your classes from ServicedComponent and run them from inside a COM+ application, and export the application proxy, so the ASP page could call your components. I use it all the time and it's very stable. My latest article: GBVB - Converting VB.NET code to C#

                  S Offline
                  S Offline
                  solidstore
                  wrote on last edited by
                  #9

                  Also is Remoting and COM Interop OK with the same object? Or should I create one object thats exposed to COM which internally calls my remote component?

                  1 Reply Last reply
                  0
                  • S solidstore

                    My remote objects derive from MarshalByRefObject and their custom COM interface. I read in a newsgroup somewhere that if you derive from this class you must call System.Runtime.Remoting.RemotingServices.Disconnect. But from where? How simple is hosting inside COM+? I'm meant to ship this week! Could anyone else confirm this is a bug in .NET? You only need a small application to test this I guess.

                    D Offline
                    D Offline
                    Daniel Turini
                    wrote on last edited by
                    #10

                    solidstore wrote: How simple is hosting inside COM+? I'm meant to ship this week! It will take you only a few minutes. For trivial objects, it's just a matter of deriving from ServicedComponent (which is indeed derived from MarshalByRefObject), put some attributes on the assembly describing the package name, and some simple configurations, and then, running regasm to put your assembly under COM+. And you'll need to remove all your service code, COM+ will take care of this for you. solidstore wrote: Could anyone else confirm this is a bug in .NET? You only need a small application to test this I guess. This raises me another (I know, obvious) question: are you with 1.1 framework? 1.0 with all SP applied? My latest article: GBVB - Converting VB.NET code to C#

                    S 2 Replies Last reply
                    0
                    • D Daniel Turini

                      solidstore wrote: How simple is hosting inside COM+? I'm meant to ship this week! It will take you only a few minutes. For trivial objects, it's just a matter of deriving from ServicedComponent (which is indeed derived from MarshalByRefObject), put some attributes on the assembly describing the package name, and some simple configurations, and then, running regasm to put your assembly under COM+. And you'll need to remove all your service code, COM+ will take care of this for you. solidstore wrote: Could anyone else confirm this is a bug in .NET? You only need a small application to test this I guess. This raises me another (I know, obvious) question: are you with 1.1 framework? 1.0 with all SP applied? My latest article: GBVB - Converting VB.NET code to C#

                      S Offline
                      S Offline
                      solidstore
                      wrote on last edited by
                      #11

                      I'm using 1.0 framework with SP2. With less than a week to go v1.1 seems a bit risky + we have lots of other apps on v1.0 that need to ship together. I'm developing & testing on XP pro but we deploy onto Win2K advanced servers. Fully patched & serviced packed in both cases.

                      1 Reply Last reply
                      0
                      • D Daniel Turini

                        solidstore wrote: How simple is hosting inside COM+? I'm meant to ship this week! It will take you only a few minutes. For trivial objects, it's just a matter of deriving from ServicedComponent (which is indeed derived from MarshalByRefObject), put some attributes on the assembly describing the package name, and some simple configurations, and then, running regasm to put your assembly under COM+. And you'll need to remove all your service code, COM+ will take care of this for you. solidstore wrote: Could anyone else confirm this is a bug in .NET? You only need a small application to test this I guess. This raises me another (I know, obvious) question: are you with 1.1 framework? 1.0 with all SP applied? My latest article: GBVB - Converting VB.NET code to C#

                        S Offline
                        S Offline
                        solidstore
                        wrote on last edited by
                        #12

                        I'm using 1.0 framework with SP2. With less than a week to go v1.1 seems a bit risky + we have lots of other apps on v1.0 that need to ship together. I'm developing & testing on XP pro but we deploy onto Win2K advanced servers. Fully patched & serviced packed in both cases. I've also made an interesting discovery: I've downloaded the SciTech memory profiler which I've attached to the Service. Things continue to leak as usually during the test, however after I create the first snapshot, it seems to start garbage collecting correctly!!!! I dont know what the profiler does but you can see that is makes some forced GCs which kick things into action. I've tried to do this myself in code by forcing collection but it didnt work. What could be causing things to suddenly work when the profiler first does something?

                        D 1 Reply Last reply
                        0
                        • S solidstore

                          I'm using 1.0 framework with SP2. With less than a week to go v1.1 seems a bit risky + we have lots of other apps on v1.0 that need to ship together. I'm developing & testing on XP pro but we deploy onto Win2K advanced servers. Fully patched & serviced packed in both cases. I've also made an interesting discovery: I've downloaded the SciTech memory profiler which I've attached to the Service. Things continue to leak as usually during the test, however after I create the first snapshot, it seems to start garbage collecting correctly!!!! I dont know what the profiler does but you can see that is makes some forced GCs which kick things into action. I've tried to do this myself in code by forcing collection but it didnt work. What could be causing things to suddenly work when the profiler first does something?

                          D Offline
                          D Offline
                          Daniel Turini
                          wrote on last edited by
                          #13

                          solidstore wrote: I've downloaded the SciTech memory profiler which I've attached to the Service. Things continue to leak as usually during the test, however after I create the first snapshot, it seems to start garbage collecting correctly!!!! I dont know what the profiler does but you can see that is makes some forced GCs which kick things into action. I've tried to do this myself in code by forcing collection but it didnt work. What could be causing things to suddenly work when the profiler first does something? Forcing collection doesn't work? Strange. It seems that you have some form of dangling pointers. You've said you are mixing remoting + COM. Can you isolate one of them, like, creating a "pure" remoting client and a "pure" COM client, to see where is the problem, or if the problem comes with mixing them? My latest article: GBVB - Converting VB.NET code to C#

                          S 1 Reply Last reply
                          0
                          • D Daniel Turini

                            solidstore wrote: I've downloaded the SciTech memory profiler which I've attached to the Service. Things continue to leak as usually during the test, however after I create the first snapshot, it seems to start garbage collecting correctly!!!! I dont know what the profiler does but you can see that is makes some forced GCs which kick things into action. I've tried to do this myself in code by forcing collection but it didnt work. What could be causing things to suddenly work when the profiler first does something? Forcing collection doesn't work? Strange. It seems that you have some form of dangling pointers. You've said you are mixing remoting + COM. Can you isolate one of them, like, creating a "pure" remoting client and a "pure" COM client, to see where is the problem, or if the problem comes with mixing them? My latest article: GBVB - Converting VB.NET code to C#

                            S Offline
                            S Offline
                            solidstore
                            wrote on last edited by
                            #14

                            good idea! do you mean create a C# exe to test the Remoting by creating the objects natively? And create another C++ client to create the COM objects but without setting up the remoting configuration? Other tests just in: I've just tried make my service run under my local administrator account (instead of SYSTEM) and the memory performance counters appear normal (although my process no longer show up in the perfmon list - I'm having to use _Global_). Could the user account being used affect GC? Why has my process/service disappeared from perfmon now I've changed the user account?

                            D 1 Reply Last reply
                            0
                            • S solidstore

                              good idea! do you mean create a C# exe to test the Remoting by creating the objects natively? And create another C++ client to create the COM objects but without setting up the remoting configuration? Other tests just in: I've just tried make my service run under my local administrator account (instead of SYSTEM) and the memory performance counters appear normal (although my process no longer show up in the perfmon list - I'm having to use _Global_). Could the user account being used affect GC? Why has my process/service disappeared from perfmon now I've changed the user account?

                              D Offline
                              D Offline
                              Daniel Turini
                              wrote on last edited by
                              #15

                              Hi, I know you probably solved your problem by now, with the account change (BTW, it shouldn't change the GC behavior), but I crossed this article on MSDN that may have some useful information to you: http://msdn.microsoft.com/library/en-us/dnadvnet/html/vbnet05272003.asp?frame=true[^] My latest article: GBVB - Converting VB.NET code to C#

                              1 Reply Last reply
                              0
                              Reply
                              • Reply as topic
                              Log in to reply
                              • Oldest to Newest
                              • Newest to Oldest
                              • Most Votes


                              • Login

                              • Don't have an account? Register

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • World
                              • Users
                              • Groups