9 Replies Latest reply on Sep 4, 2006 12:07 PM by Elijah Epifanov

    What should I create to frequently ask it for smart clones??

    Elijah Epifanov Newbie

      Which class encapsulates all data needed to recreate smart clone for a particular object?

      The main idea is to reuse final objects pool and recreate smart clones not from raw bytes.

      I tried DataContainer, but its DataContainerInput isn't thread safe and occasionally throws this:

      Exception in thread "Thread-24" java.lang.RuntimeException: java.io.IOException
      ....
      Caused by: java.io.IOException
      at org.jboss.serial.persister.RegularObjectPersister.readSlotWithMethod(RegularObjectPersister.java:103)
      at org.jboss.serial.persister.RegularObjectPersister.defaultRead(RegularObjectPersister.java:250)
      at org.jboss.serial.persister.RegularObjectPersister.readData(RegularObjectPersister.java:228)
      at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:339)
      at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:63)
      at org.jboss.serial.objectmetamodel.DataContainer$DataContainerInput.readObject(DataContainer.java:735)
      at org.jboss.serial.persister.RegularObjectPersister.readSlotWithFields(RegularObjectPersister.java:302)
      at org.jboss.serial.persister.RegularObjectPersister.defaultRead(RegularObjectPersister.java:252)
      at org.jboss.serial.persister.RegularObjectPersister.readData(RegularObjectPersister.java:228)
      at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:339)
      at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:63)
      at org.jboss.serial.objectmetamodel.DataContainer$DataContainerInput.readObject(DataContainer.java:735)
      at ws.xmart.dynamic.JBossSmartCloningFilter.restore(JBossSmartCloningFilter.java:35)
      ... 4 more
      Caused by: java.lang.reflect.InvocationTargetException
      at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:585)
      at org.jboss.serial.persister.RegularObjectPersister.readSlotWithMethod(RegularObjectPersister.java:97)
      ... 16 more
      Caused by: java.io.EOFException: Unexpected end of repository
      at org.jboss.serial.objectmetamodel.DataContainer$DataContainerInput.moveNext(DataContainer.java:724)
      at org.jboss.serial.objectmetamodel.DataContainer$DataContainerInput.readInt(DataContainer.java:903)
      at org.jboss.serial.persister.RegularObjectPersister.readSlotWithFields(RegularObjectPersister.java:282)
      at org.jboss.serial.persister.RegularObjectPersister.defaultRead(RegularObjectPersister.java:252)
      at org.jboss.serial.persister.RegularObjectPersister.readData(RegularObjectPersister.java:228)
      at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:339)
      at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:63)
      at org.jboss.serial.objectmetamodel.DataContainer$DataContainerInput.readObject(DataContainer.java:735)
      at org.jboss.serial.persister.RegularObjectPersister.readSlotWithFields(RegularObjectPersister.java:302)
      at org.jboss.serial.persister.RegularObjectPersister.defaultRead(RegularObjectPersister.java:252)
      at org.jboss.serial.persister.RegularObjectPersister.readData(RegularObjectPersister.java:228)
      at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:339)
      at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:63)
      at org.jboss.serial.objectmetamodel.DataContainer$DataContainerInput.readObject(DataContainer.java:735)
      at org.jboss.serial.persister.ArrayPersister.readObjectArray(ArrayPersister.java:217)
      at org.jboss.serial.persister.ArrayPersister.readData(ArrayPersister.java:196)
      at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:339)
      at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:63)
      at org.jboss.serial.objectmetamodel.DataContainer$DataContainerInput.readObject(DataContainer.java:735)
      at org.jboss.serial.persister.RegularObjectPersister.readSlotWithFields(RegularObjectPersister.java:302)
      at org.jboss.serial.persister.ObjectInputStreamProxy.defaultReadObject(ObjectInputStreamProxy.java:72)
      at java.util.concurrent.ConcurrentHashMap.readObject(ConcurrentHashMap.java:1399)
      ... 20 more

        • 1. Re: What should I create to frequently ask it for smart clon
          Clebert Suconic Master

          DataContainer was not meant to be ThreadSafe. I've never done any tests reusing the same instance in a MultiThread environment.

          I guess you would do that to use DataContainer as a FactoryObject. (Is that correct?)


          I double checked DataContainer, and if you use it read-only, it should be thread Safe, as long you don't reuse DataContainerInputs...


          So,


          If you have a DataContainer, you should always do:

          DataContainer source= .... init somehow ...


          each Thread...


          ObjectInput input = source.getInput(); // don't reuse these inputs.


          But again.. I haven't tested this with the exact same scenario you arer using it.


          Clebert Suconic

          • 2. Re: What should I create to frequently ask it for smart clon
            Elijah Epifanov Newbie

            Thank you Clebert )

            I am already doing exactly this, and this is thread-safe for read-access.
            Here is the benchmark for my cache implementation:

            Sun JDK 1.5.0_07 (x64):
            Without Serialization: 2.3713 usec
            JBossSmartClone (DataContainer): 44.784 usec
            JBossSerialization: 68.773 usec
            JavaSerialization: 167.959 usec

            Sun JDK 1.6.0_rc (x64):
            Without Serialization: 2.1233 usec
            JBossSmartClone (DataContainer): 34.639 usec
            JBossSerialization: 57.145 usec
            JavaSerialization: 152.6278 usec

            (Note that x64 JDK6 doesn't offer much performance gain, unlike x86 one)

            Amount of garbage generated is HUGE for all 3 copying methods.
            Approximate proportions are:
            JBossSmartClone: 300MB
            JBossSerialization: 800MB
            JavaSerialization: 1200MB

            Much of the garbage comes from ArrayList resizing algorithm, THash rehashing, etc.

            I'll try to patch some code to use Javolution's PoolContexts. Maybe this will help.

            • 3. Re: What should I create to frequently ask it for smart clon
              Elijah Epifanov Newbie

              Thank you Clebert )

              I am already doing exactly this, and this is thread-safe for read-access.
              Here is the benchmark for my cache implementation:

              Sun JDK 1.5.0_07 (x64):
              Without Serialization: 2.3713 usec
              JBossSmartClone (DataContainer): 44.784 usec
              JBossSerialization: 68.773 usec
              JavaSerialization: 167.959 usec

              Sun JDK 1.6.0_rc (x64):
              Without Serialization: 2.1233 usec
              JBossSmartClone (DataContainer): 34.639 usec
              JBossSerialization: 57.145 usec
              JavaSerialization: 152.6278 usec

              (Note that x64 JDK6 doesn't offer much performance gain, unlike x86 one)

              Amount of garbage generated is HUGE for all 3 copying methods.
              Approximate proportions are:
              JBossSmartClone: 300MB
              JBossSerialization: 800MB
              JavaSerialization: 1200MB

              Much of the garbage comes from ArrayList resizing algorithm, THash rehashing, etc.

              I'll try to patch some code to use Javolution's PoolContexts. Maybe this will help.

              • 4. Re: What should I create to frequently ask it for smart clon
                Elijah Epifanov Newbie

                Oooops.

                Only works with:
                synchronized (container) {
                ObjectInput input = container.getInput();
                Object ret = input.readObject();
                input.close();
                return (I) ret;
                }


                When unsynchronized, the stacktrace in first post pops up.

                • 5. Re: What should I create to frequently ask it for smart clon
                  Elijah Epifanov Newbie

                  Heh..
                  DataContainer isn't thread-safe.
                  DataContainerInput writes to it.


                  public Object readObject() throws ClassNotFoundException, IOException {
                  DataContainer.this.cache.setInput(this);
                  return ObjectDescriptorFactory.objectFromDescription(DataContainer.this.cache, this);
                  }

                  • 6. Re: What should I create to frequently ask it for smart clon
                    Clebert Suconic Master

                    Yes, you're right.

                    What's your use case? Why you need to reuse a single DataContainer among different threads.

                    All the use cases we have at this point for JBossSerialization were to clone objects during call invocations, what would require a DataContainer per thread. (So we create the DataContainer each time we need a serialization clone).

                    It looks like you are using it to a factory's pattern.

                    • 7. Re: What should I create to frequently ask it for smart clon
                      Clebert Suconic Master

                      DataContainer can't be multi-thread because ObjectsCache and the hashmap of read objects is stored inside DataContainer.

                      However, look at this:

                      http://jira.jboss.org/jira/browse/JBSER-88


                      Just created a new method on DataContainer called .cloneContainer.

                      You can have a DataContainer per thread with this, reusing the ArrayList underneath DataContainer used to store the data. You would minimize GC with this factory pattern.

                      Although you will have to use CVS for a while.


                      Take a look on org.jboss.serial.soaktest.DataContainerMultiThreadTestCase.

                      DataContainer is being cloned and reused among 100 threads, each thread reading 100 times the same object. All having a single source.


                      So... I created the feature just for you (as it was simple creating it). As an exchange now, can you provide me what would be a nice UseCase? :-)


                      Clebert Suconic

                      • 8. Re: What should I create to frequently ask it for smart clon
                        Clebert Suconic Master

                         

                        I'll try to patch some code to use Javolution's PoolContexts. Maybe this will help.



                        If you could expand your idea here also, please.


                        Clebert Suconic

                        • 9. Re: What should I create to frequently ask it for smart clon
                          Elijah Epifanov Newbie

                           

                          "clebert.suconic@jboss.com" wrote:

                          So... I created the feature just for you (as it was simple creating it). As an exchange now, can you provide me what would be a nice UseCase? :-)


                          ))

                          I am implementing a highly concurrent cache for an in-house project. Currently it performs faster than other caches, and it has some useful features included by default (like blocking concurrent threads getting the same value). The key of performance gain is the use of highly nondeterministic algorithms, which achieve this boost at the price of providing much weaker guarantees. Later (if my employeer will allow this:)) I will opensource it.

                          Thanks