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. Object lifetime, GC and the State Pattern [modified]

Object lifetime, GC and the State Pattern [modified]

Scheduled Pinned Locked Moved C#
designregexarchitectureperformancequestion
8 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.
  • L Offline
    L Offline
    Lost User
    wrote on last edited by
    #1

    Hi everybody I'm currently experimenting with design patterns, one of them is the design pattern. First some code: This will init my application, it will init itself then by switching from state to state

    static void Main(string[] args)
    {
    ScreenInitState startState = ScreenInitState.GetInstance();
    Console.WriteLine("All states exited");

    Console.WriteLine("Press any key to exit.");
    Console.ReadKey();
    

    }

    Here we switch from state to state

    abstract class InitState
    {
    protected void Switch(InitState state, bool bStopSelf)
    {
    if (bStopSelf)
    Stop();
    }

    abstract protected void Stop();
    

    }

    class ScreenInitState : InitState
    {
    private ScreenInitState()
    {
    // init screen here and go to next state

    	Switch(InputInitState.GetInstance(), true);
    }
    
    // ...
    

    }

    class InputInitState : InitState
    {
    private InputInitState()
    {
    // init input here and go to next state

    	Switch(SoundInitState.GetInstance(), true);
    }
    
    // ...
    

    }

    So the app starts like this: Main -> SreenInitState -> InputInitState -> SoundInitState -> ... Now when I'm in the last state, do all previous states still exist in memory or are the collected by the GC? Though this pattern is very useful I'm concerned about memory usage here. Does anyone know what happens to the objects during runtime? regards -- modified at 9:54 Tuesday 6th June, 2006

    S G 2 Replies Last reply
    0
    • L Lost User

      Hi everybody I'm currently experimenting with design patterns, one of them is the design pattern. First some code: This will init my application, it will init itself then by switching from state to state

      static void Main(string[] args)
      {
      ScreenInitState startState = ScreenInitState.GetInstance();
      Console.WriteLine("All states exited");

      Console.WriteLine("Press any key to exit.");
      Console.ReadKey();
      

      }

      Here we switch from state to state

      abstract class InitState
      {
      protected void Switch(InitState state, bool bStopSelf)
      {
      if (bStopSelf)
      Stop();
      }

      abstract protected void Stop();
      

      }

      class ScreenInitState : InitState
      {
      private ScreenInitState()
      {
      // init screen here and go to next state

      	Switch(InputInitState.GetInstance(), true);
      }
      
      // ...
      

      }

      class InputInitState : InitState
      {
      private InputInitState()
      {
      // init input here and go to next state

      	Switch(SoundInitState.GetInstance(), true);
      }
      
      // ...
      

      }

      So the app starts like this: Main -> SreenInitState -> InputInitState -> SoundInitState -> ... Now when I'm in the last state, do all previous states still exist in memory or are the collected by the GC? Though this pattern is very useful I'm concerned about memory usage here. Does anyone know what happens to the objects during runtime? regards -- modified at 9:54 Tuesday 6th June, 2006

      S Offline
      S Offline
      Stephan Samuel
      wrote on last edited by
      #2

      What's behind SoundInitState.GetInstance()? Every time I've written something with an Instance property or a GetInstance(), it's been a singleton. If all of your states are singletons, the GC isn't collecting them. Also, what does Stop() do in each of the states? You'd need to be designing something pretty complicated to warrant singleton states. In general, states work better as flyweights. I'd say use structs, but they break the inheritance model.

      L 1 Reply Last reply
      0
      • S Stephan Samuel

        What's behind SoundInitState.GetInstance()? Every time I've written something with an Instance property or a GetInstance(), it's been a singleton. If all of your states are singletons, the GC isn't collecting them. Also, what does Stop() do in each of the states? You'd need to be designing something pretty complicated to warrant singleton states. In general, states work better as flyweights. I'd say use structs, but they break the inheritance model.

        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #3

        Stephan Samuel wrote:

        What's behind SoundInitState.GetInstance()? Every time I've written something with an Instance property or a GetInstance(), it's been a singleton.

        Correct, that's the case here

        Stephan Samuel wrote:

        Also, what does Stop() do in each of the states?

        Just a function where the state will cleanup itself (remove resources etc) before switching to the next state

        Stephan Samuel wrote:

        the GC isn't collecting them

        So you suggest to use some sort of structs + switch-calls to keep the memory footprint as small as possible? Or does it help to design my states as normal instances instead of singletons?

        S 1 Reply Last reply
        0
        • L Lost User

          Hi everybody I'm currently experimenting with design patterns, one of them is the design pattern. First some code: This will init my application, it will init itself then by switching from state to state

          static void Main(string[] args)
          {
          ScreenInitState startState = ScreenInitState.GetInstance();
          Console.WriteLine("All states exited");

          Console.WriteLine("Press any key to exit.");
          Console.ReadKey();
          

          }

          Here we switch from state to state

          abstract class InitState
          {
          protected void Switch(InitState state, bool bStopSelf)
          {
          if (bStopSelf)
          Stop();
          }

          abstract protected void Stop();
          

          }

          class ScreenInitState : InitState
          {
          private ScreenInitState()
          {
          // init screen here and go to next state

          	Switch(InputInitState.GetInstance(), true);
          }
          
          // ...
          

          }

          class InputInitState : InitState
          {
          private InputInitState()
          {
          // init input here and go to next state

          	Switch(SoundInitState.GetInstance(), true);
          }
          
          // ...
          

          }

          So the app starts like this: Main -> SreenInitState -> InputInitState -> SoundInitState -> ... Now when I'm in the last state, do all previous states still exist in memory or are the collected by the GC? Though this pattern is very useful I'm concerned about memory usage here. Does anyone know what happens to the objects during runtime? regards -- modified at 9:54 Tuesday 6th June, 2006

          G Offline
          G Offline
          Guffa
          wrote on last edited by
          #4

          As you are switching from state to state by using a method in each object, the objects can't be garbage collected. The Switch method of each previous state is still executing until the last state is finished. When the last state returns from the Switch method, all previous Switch calls will finish in turn and release the objects. This is not a problem, however, as long as you make the Stop method release all objects contained in it's state object. --- b { font-weight: normal; }

          L 1 Reply Last reply
          0
          • G Guffa

            As you are switching from state to state by using a method in each object, the objects can't be garbage collected. The Switch method of each previous state is still executing until the last state is finished. When the last state returns from the Switch method, all previous Switch calls will finish in turn and release the objects. This is not a problem, however, as long as you make the Stop method release all objects contained in it's state object. --- b { font-weight: normal; }

            L Offline
            L Offline
            Lost User
            wrote on last edited by
            #5

            Guffa wrote:

            This is not a problem, however, as long as you make the Stop method release all objects contained in it's state object.

            That's what I do. So the only thing left in memory will be the instance of the state objects and nothing more? I hope this isn't too much overhead as a drawback for clean design.

            G 1 Reply Last reply
            0
            • L Lost User

              Stephan Samuel wrote:

              What's behind SoundInitState.GetInstance()? Every time I've written something with an Instance property or a GetInstance(), it's been a singleton.

              Correct, that's the case here

              Stephan Samuel wrote:

              Also, what does Stop() do in each of the states?

              Just a function where the state will cleanup itself (remove resources etc) before switching to the next state

              Stephan Samuel wrote:

              the GC isn't collecting them

              So you suggest to use some sort of structs + switch-calls to keep the memory footprint as small as possible? Or does it help to design my states as normal instances instead of singletons?

              S Offline
              S Offline
              Stephan Samuel
              wrote on last edited by
              #6

              You should keep your states small. Structs won't work because they don't implement inheritance, but try to keep the information inside your concrete state classes to a minimum. I would avoid the singleton pattern for states. Currently, your states don't really switch. Each tunnels through to the next. There should probably be one top-level controller (it may be a singleton but may not need to be) that decides which state you're in and runs the states: (Please pardon any typos or syntax errors; I'm making this up as I go.) public class MyController { State currentState; public void RunMe() { while (this.currentState != null) this.currentState = this.currentState.RunMe(); } } public abstract class State { public abstract State RunMe(); } public class ConcreteState1() { public RunMe() { // do things. return new ConcreteState2(); } } public class ConcreteState2() { public RunMe() { // do things. return null; } } Likely, you'll want to pass around some objects, and your states will pass out different "next state" objects as RunMe() returns based on what those objects look like. Each state lives only as long as it's executing, so there's no memory overhead. If you're worried about setup/tear-down performance of your state objects (e.g. -- if they have a complicated DB open process and you need them to run really quickly with persistent connections), consider some level of factory for the states: either have a connection factory, give each state its own factory and let it decide when to create a new one of itself, or create a factory class (or implement one in MyController) that decides the lifetime of your state objects. I'd also implement IDisposable and the C# disposal pattern for each of your state objects to clear up unmanaged resources. Managed resources should get cleaned up automatically. The other way to implement this is to have MyController decide which state is next based on the state of some object. My personal belief is that method isn't as good. It's less OO: you might as well just code all the possibilities within the controller and forget the states.

              L 1 Reply Last reply
              0
              • S Stephan Samuel

                You should keep your states small. Structs won't work because they don't implement inheritance, but try to keep the information inside your concrete state classes to a minimum. I would avoid the singleton pattern for states. Currently, your states don't really switch. Each tunnels through to the next. There should probably be one top-level controller (it may be a singleton but may not need to be) that decides which state you're in and runs the states: (Please pardon any typos or syntax errors; I'm making this up as I go.) public class MyController { State currentState; public void RunMe() { while (this.currentState != null) this.currentState = this.currentState.RunMe(); } } public abstract class State { public abstract State RunMe(); } public class ConcreteState1() { public RunMe() { // do things. return new ConcreteState2(); } } public class ConcreteState2() { public RunMe() { // do things. return null; } } Likely, you'll want to pass around some objects, and your states will pass out different "next state" objects as RunMe() returns based on what those objects look like. Each state lives only as long as it's executing, so there's no memory overhead. If you're worried about setup/tear-down performance of your state objects (e.g. -- if they have a complicated DB open process and you need them to run really quickly with persistent connections), consider some level of factory for the states: either have a connection factory, give each state its own factory and let it decide when to create a new one of itself, or create a factory class (or implement one in MyController) that decides the lifetime of your state objects. I'd also implement IDisposable and the C# disposal pattern for each of your state objects to clear up unmanaged resources. Managed resources should get cleaned up automatically. The other way to implement this is to have MyController decide which state is next based on the state of some object. My personal belief is that method isn't as good. It's less OO: you might as well just code all the possibilities within the controller and forget the states.

                L Offline
                L Offline
                Lost User
                wrote on last edited by
                #7

                Great. The Controller object really makes sense and keeps memory overhead at a minimum, that's a really good way, I like. The only addition I will make is to keep a Stack<State> in my controller, so that some states will still be able to overlap each other, like a menu on top of a game. Thanks a bunch! :)

                1 Reply Last reply
                0
                • L Lost User

                  Guffa wrote:

                  This is not a problem, however, as long as you make the Stop method release all objects contained in it's state object.

                  That's what I do. So the only thing left in memory will be the instance of the state objects and nothing more? I hope this isn't too much overhead as a drawback for clean design.

                  G Offline
                  G Offline
                  Guffa
                  wrote on last edited by
                  #8

                  Greeeg wrote:

                  So the only thing left in memory will be the instance of the state objects and nothing more?

                  If you get rid of all references in the object (setting them to null), all objects that it used are up for garbage collection. If the memory is needed, they will be collected. --- b { font-weight: normal; }

                  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