Ok, maybe I wasn't clear enough with my description:
The current display of component sizes on the error page is bogus.

Many component instances are based on anonymous inner classes and have a reference to their enclosing component. If asked for their size they'll always include the size of their parental component hierarchy. Nullifying the parent previously to streaming the component into the ObjectOutputStream won't help here.

Johan was right in that my solution doesn't cater for his example. But the following implementation works in this case too:

public class IsolatingObjectObjectStream extends ObjectOutputStream {
        private Component isolate;
                
        public StoppingObjectObjectStream(OutputStream out, Component isolate) 
throws IOException {
                super(out);
                        
                this.isolate = isolate;
                
                enableReplaceObject(true);
        }
        
        protected Object replaceObject(Object obj) throws IOException {
                Component parent = isolate.getParent();
                
                // cut off obj if it is referring to a parental component
                while (parent != null) {
                        if (obj == parent) {
                                return null;
                        }
                        parent = parent.getParent();
                }
                return super.replaceObject(obj);
        }
}

This specialized stream isolates a component, i.e. it will cut off all references from inside a components subtree to any of its parental components.

Please just give it a try and see how the reported sizes on the error page drop down. I'd call this an accurate representation.

Sven

Igor Vaynberg wrote:

the reason its set to null is that when it is serialized into session most
likely the parent would have already been serialized and thus it would just
be a reference and not a another full serialized version. so this function
gives an accurate representation of this component /in session/.

-Igor


On 1/24/06, Johan Compagner <[EMAIL PROTECTED]> wrote:
If you want to calculated the model size then yes that is the full size of
the model. (so including the parent)
because that is how it gets serialized anyway (in session and in model
cloning)
And what is the parent?
You now just say component.getParent()
But that doesn't have to be the one of the anon innerclass...

Form form = new Form()
formComponent = new FormComponent()
{
// inner
}
form.add(formComponent)
this.add(form) (this == page)

what happens now?

It would be nice to get this advanced also in model cloning that we know
what object we don't want to clone
but to keep the original references to!!
If then a model is cloned but that model does reference a parent or a page
then we don't serialize that but keep a reference
somehow to the real object.... That would be nice...


johan



On 1/24/06, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
Sorry if this has been discussed before (or if I'm completely wrong on
this):

It seems that Component#getSizeInBytes() gives wrong results in case of
non-static nested classes (which is quite common in Wicket):

public LoginPage() {
add(new Link("login") {
  public void onClick() {
    ...
  }
});
}
Yes, Component#getSizeInBytes() sets the parent reference to null before
calling Objects.sizeof(this).
But the reference to the enclosing object (this$0) will trigger a
serialization of the complete page, thus resulting in a wrong size
calculation.

I've experimented a little bit and came up with the following solution
that nullifies any reference to a configurable 'stop' object:

Objects.java:
public static long sizeof(final Object object, final Object stopObject)
{
try
{
  final ByteCountingOutputStream out = new
ByteCountingOutputStream();
  new StoppingObjectObjectStream(out,
stopObject).writeObject(object);
  out.close();
  return out.size();
}
catch (IOException e)
{
  e.printStackTrace();
  return -1;
}
}
StoppingObjectObjectStream.java:
public class StoppingObjectObjectStream extends ObjectOutputStream {
private Object stopObject;
public StoppingObjectObjectStream(OutputStream out,
    Object stopObject) throws IOException {
  super(out);

  this.stopObject = stopObject;

  enableReplaceObject(true);
}

protected Object replaceObject(Object obj) throws IOException {
  if (obj == stopObject) {
     return null;
  }
  return super.replaceObject(obj);
}
}
Now there's no need any more to nullify the parent of the component and
resetting it afterwards in Component.java :
public long getSizeInBytes()
{
return Objects.sizeof(this, getParent());
}
What do you think? Perhaps a little bit freaky I must admit.

Sven


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log
files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=103432&bid=230486&dat=121642
_______________________________________________
Wicket-user mailing list
Wicket-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wicket-user






-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=103432&bid=230486&dat=121642
_______________________________________________
Wicket-user mailing list
Wicket-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wicket-user

Reply via email to