2 Replies Latest reply on Sep 14, 2018 6:18 AM by Garima Kemwal

    Lifetime and scope of Helper Classes in Byteman

    Garima Kemwal Newbie

      Hi team,

       

      I was able to put together an injection application after a previous discussion here.

      Also took your suggestion on getting bootstrap and system helpers to communicate :

      Alternatively, your bootstrap path helper can write static data which can be read by the system path helper

       

      While this approach works as expected. I'm curious how this would impact the memory heap.

      The documentation mentions that 'Byteman needs to be able to instantiate your helper when the rule is triggered'.

       

      It would be great if you could give some insight on the following aspects :

      1. How often does this helper instantiation happen after loading of rules?
      2. If the helper class gets instantiated as an object as mentioned, when does this object get Garbage Collected, is it as soon as the rule ends or at the preemption of the current thread?
      3. If the flow in which the helper is used gets invoked in every thread, hypothetically 5 threads, will it also lead to creation of 5 different objects?

       

      Looking to determine how to handle static/threadlocal instance variables in helper classes in a multithreaded environment safely, if you have any suggestions there.

       

      Configuration: This is a spring boot application.

       

      Thanks!

        • 1. Re: Lifetime and scope of Helper Classes in Byteman
          Andrew Dinn Master

          Hi Garima,

           

          garimakemwal  wrote:

           

          Hi team,

           

          I was able to put together an injection application after a previous discussion Bytecode not refreshed on runtime rule injection | java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest .

           

          Excellent., Glad to hear you have been making progress.

           

          garimakemwal  wrote:

           

          Also took your suggestion on getting bootstrap and system helpers to communicate :

          Alternatively, your bootstrap path helper can write static data which can be read by the system path helper

           

          While this approach works as expected. I'm curious how this would impact the memory heap.

          The documentation mentions that 'Byteman needs to be able to instantiate your helper when the rule is triggered'.

           

          It would be great if you could give some insight on the following aspects :

          1. How often does this helper instantiation happen after loading of rules?
          2. If the helper class gets instantiated as an object as mentioned, when does this object get Garbage Collected, is it as soon as the rule ends or at the preemption of the current thread?
          3. If the flow in which the helper is used gets invoked in every thread, hypothetically 5 threads, will it also lead to creation of 5 different objects?

           

          garimakemwal  wrote:

           

          Hi team,

           

          I was able to put together an injection application after a previo


          Hi team,

           

          I was able to put together an injection application after a previous discussion Bytecode not refreshed on runtime rule injection | java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest .

           

          Excellent., Glad to hear you have been making progress.

           

          garimakemwal  wrote:


          Also took your suggestion on getting bootstrap and system helpers to communicate :

          Alternatively, your bootstrap path helper can write static data which can be read by the system path helper

           

          While this approach works as expected. I'm curious how this would impact the memory heap.

          The documentation mentions that 'Byteman needs to be able to instantiate your helper when the rule is triggered'.

           

          It would be great if you could give some insight on the following aspects :

          1. How often does this helper instantiation happen after loading of rules?
          2. If  the helper class gets instantiated as an object as mentioned, when does  this object get Garbage Collected, is it as soon as the rule ends or at  the preemption of the current thread?
          3. If the flow in which the  helper is used gets invoked in every thread, hypothetically 5 threads,  will it also lead to creation of 5 different objects?

           

          Sure, no problem:

           

          1) A helper instance is created every time a rule using that helper is triggered i.e. every time control reaches an injection point. If two rules are injected at the same point then a helper is created for each rule triggering.

           

          2) The helper instance will normally be eligible for garbage collection as soon as control returns back from the injected code to the original bytecode. I have not guarded that statement with the word 'normally' because Byteman might sometimes retain a reference to the Helper instance but because of what your helper code might do. If one of your helper methods inserts a reference to the helper instance into a static variable or some other reachable location then that might keep it alive beyond the point where control is returned.

           

          3) Yes, an object is created every time control reaches the injection point for a rule. So, each thread will get its own helper instance created.

           

          I'll expose a small wrinkle here that explains that last answer and also a bit more about the object creation. What gets created is an instance of a subclass of your helper class. Why? Well, in order for Byteman to interact with your helper while executing the rule it needs to be able to pass it bindings for method parameters, local vars and special vars ($!, $^ etc). It also needs to be able to get it to co-operate in executing the rule code.

           

          So, Byteman defines a subclass of your helper at runtime when a rule that mentions it is loaded which includes some extra fields and methods. The fields store the values for the vars passed from the injection point. The methods implement an interface called HelperInterface which allow the created instance to execute the rule code. For compiled methods the rule is executed by generated bytecode of this class. For non-compiled methods the rule is executed by interpreting the parse tree.

           

          So, anyway, the upshot is that the object that gets created will have some extra fields and methods.

           

          n.b. also, in case you are worrying,  when your rule is unloaded the Byetman defined subclass is also able to be unloaded by the garbage collector.

           

          Looking to determine how to handle static/threadlocal instance variables in helper classes in a multithreaded environment safely, if you have any suggestions there.

           

          Configuration: This is a spring boot application.

           

          Most of the standard Helper methods have been implemented to work in a multi-threaded runtime (for example, Counters or Countdowns do atomic increments or decrements). If you want to make your helper thread-safe you need to ensure that you synchronize when updating potentially shared state. You don't need to worry about state local to the helper instance because each thread will be operating on its own instance.

           

          Hope that answers your questions satisfactorily. Please ask if you need more details or anything is not clear.

           

          regards,

           

           

          Andrew Dinn

          1 of 1 people found this helpful
          • 2. Re: Lifetime and scope of Helper Classes in Byteman
            Garima Kemwal Newbie

            Hi Andrew,

             

            That's a very comprehensive explanation, thank you! That gives a lot insight on the memory heap usage and thread safety in byteman.

             

            Thanks

            Garima