from JPA experience, eager loading of List of Entities is part of what hogs
memory. I have profiles an application before that the memory  usage just
kept growing each time my page reference a particular entity that eager
loads other collection of entities. As soon as I removed the eager load
annotation, my memory usage became quite stable.

if you need the reference your collections, just take another trip to the
database and fetch them.

Beware of some JPA providers, they also hog memory too.

I am not saying this is the problem in your case, yu may choose to look into
it and give that a try.


just dropped by

cheers

dabar

On 4/2/08, Java Programmer <[EMAIL PROTECTED]> wrote:
>
> Hello,
> We have problem with serializing webpages - the user session files
> growing rapidly (each request about 100KB), we don't know what we have
> did wrong - system is based on examples from wicket.apache.org, so it
> should work but this large files (10-20MB for some time, after many
> request) slows it down.
> We have tried to put transient in all fields which we are use as
> components on WebPages - it doesn't help.
> Maybe I put some code and little explain and you can tell us whay is
> wrong.
> The example will be consider LinkTree with 2000+ categories:
> Categories we have as Hibernate Entity cached whole in ehcache in memory:
> @Entity
> @Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
> public class Category implements Serializable {
>
>         @Id
>         @GeneratedValue(strategy = GenerationType.AUTO)
>         private Integer id;
>
>         private String name;
>
>         private String description;
>
>         @Enumerated(value = EnumType.STRING)
>         private CategoryStatus categoryStatus;
>
>         @ManyToOne(fetch=FetchType.EAGER)
>         @JoinColumn(name="parent_id", insertable=false, updatable=false,
> nullable=true)
>         @Cascade(org.hibernate.annotations.CascadeType.ALL)
>         @Fetch(value=FetchMode.SELECT)
>         @Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
>         private Category parent;
>
>         @OneToMany(fetch=FetchType.EAGER)
>         @JoinColumn(name="parent_id")
>         @Cascade(org.hibernate.annotations.CascadeType.ALL)
>         @IndexColumn(name="list_id")
>         @Fetch(value=FetchMode.SELECT)
>         @Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
>         private List<Category> children = new ArrayList<Category> ();
>
>         @Index(name = "categoryPathIndex")
>         private String categoryPath = "";
>
>         public Category addChild(Category child) {
>                 child.parent = this;
>                 children.add(child);
>                 return this;
>         }
>
> //getters setters hashcode equals
> }
>
> Next we put the categories on panel as:
> public class CategoryTreePanel extends Panel {
>
>         private final transient Log LOG =
> LogFactory.getLog(CategoryTreePanel.class);
>
>         private transient Category activeCategory;
>
>         private transient TreeNode treeNode;
>
>         private transient LinkTree tree;
>
>     public CategoryTreePanel(String id, List<Category> rootCategory) {
>         this(id, rootCategory, null);
>     }
>
>     public CategoryTreePanel(String id, List<Category> rootCategory,
> Category activeCategory) {
>         super(id);
>         LOG.info("activeCategory: " + activeCategory);
>         this.activeCategory = activeCategory;
>         tree = new CarPartsLinkTree("category_tree",
> createTreeModel(rootCategory));
>                 tree.setRootLess(true);
>                 LOG.info("treeNode: " + treeNode);
>                 if(treeNode != null) {
>                         expandAllParentNodes(tree, treeNode);
>                         tree.getTreeState().selectNode(treeNode, true);
>                 } else {
>                         tree.getTreeState().collapseAll();
>                 }
>                 add(tree);
>     }
>
>     class CarPartsLinkTree extends LinkTree {
>
>                 public CarPartsLinkTree(String id, TreeModel model) {
>                         super(id, model);
>                 }
>
>                 @Override
>                 protected void onNodeLinkClicked(TreeNode node, BaseTree
> tree,
> AjaxRequestTarget target) {
>                         super.onNodeLinkClicked(node, tree, target);
>                         int catId = ((CategoryTreeNode)
> ((DefaultMutableTreeNode)
> node).getUserObject()).getCategory().getId();
>                         setRedirect(true);
>                         Page page = getPage();
>                         if(page instanceof AdvertismentsList || page
> instanceof AddAdvertisement) {
>                                 setResponsePage(getPage().getClass(), new
> PageParameters("category=" + catId));
>                         } else {
>                                 setResponsePage(AdvertismentsList.class,
> new
> PageParameters("category=" + catId));
>                         }
>                 }
>                 @Override
>                 protected ResourceReference getCSS() {
>                         return null;
>                 }
>
>                 protected Component newNodeComponent(String id, IModel
> model) {
>                         return new LinkIconPanel(id, model,
> CarPartsLinkTree.this) {
>                                 private static final long serialVersionUID
> = 1L;
>
>                                 protected void onNodeLinkClicked(TreeNode
> node, BaseTree tree,
> AjaxRequestTarget target)
>                                 {
>                                         super.onNodeLinkClicked(node,
> tree, target);
>                                         
> CarPartsLinkTree.this.onNodeLinkClicked(node,
> tree, target);
>                                 }
>
>                                 protected Component
> newContentComponent(String componentId,
> BaseTree tree, IModel model)
>                                 {
>                                         return new Label(componentId,
> getNodeTextModel(model));
>                                 }
>
>                                 @Override
>                                 protected ResourceReference
> getResourceFolderOpen(TreeNode node) {
>                                         return new
> ResourceReference(CategoryTreePanel.class,
> "res/folder-open.gif");
>                                 }
>
>                                 @Override
>                                 protected ResourceReference
> getResourceFolderClosed(TreeNode node) {
>                                         return new
> ResourceReference(CategoryTreePanel.class,
> "res/folder-closed.gif");
>                                 }
>
>                                 @Override
>                                 protected ResourceReference
> getResourceItemLeaf(TreeNode node) {
>                                         return new
> ResourceReference(CategoryTreePanel.class, "res/item.gif");
>                                 }
>                         };
>                 }
>     }
>
>     private void expandAllParentNodes(AbstractTree tree, TreeNode
> treeNode) {
>         tree.getTreeState().expandNode(treeNode);
>         if(treeNode.getParent() != null) {
>                 expandAllParentNodes(tree, treeNode.getParent());
>         }
>     }
>
>     private TreeModel createTreeModel(List<Category> rootCategories) {
>         TreeModel model = null;
>         DefaultMutableTreeNode rootNode = new
> DefaultMutableTreeNode("rootCategory");
>         add(rootNode, rootCategories);
>         model = new DefaultTreeModel(rootNode);
>         return model;
>     }
>
>     private class CategoryTreeNode {
>
>         private Category category;
>
>         public CategoryTreeNode(Category category) {
>                         super();
>                         this.category = category;
>                 }
>
>                 public Category getCategory() {
>                         return category;
>                 }
>
>                 public void setCategory(Category category) {
>                         this.category = category;
>                 }
>
>                 public String toString() {
>                 return category.getName();
>         }
>     }
>
>     private void add(DefaultMutableTreeNode parent, List<Category> sub) {
>         for (Iterator<Category> i = sub.iterator(); i.hasNext();) {
>                 Category category = i.next();
>             DefaultMutableTreeNode child = new
> DefaultMutableTreeNode(new CategoryTreeNode(category));
>             parent.add(child);
>                 if(category.equals(activeCategory)) {
>                         treeNode = child;
>                 }
>             if(category.getChildren().size() > 0) {
>                 add(child, category.getChildren());
>             }
>         }
>     }
>
> }
>
> Next we put panel on the page:
> public abstract class CommonWebPage extends WebPage {
>
>         @SpringBean
>         private transient SessionService sessionService;
>
>         @SpringBean
>         private transient CategoryDAO categoryDAO;
>
>         //some reusabale elements
>         public static final String ID_PARAMETER = "id";
>         private static final String CATEGORY_PARAMETER = "category";
>         public static final String EMPTY_STRING = "";
>
>         public static final String EQUALS = "=";
>         protected static final char DOT_SEPERATOR = '.';
>         protected static final String[] ALLOWED_PICTURES_TYPES = new
> String[]
> {"jpg", "gif", "jpeg", "png"};
>         public static final String ONCHANGE_BEHAVIOR = "onchange";
>         public static final String ONCLICK_BEHAVIOR = "onclick";
>
>         //wicket:ids
>         private static final String CATEGORIES = "categories";
>         private static final String MAIN_MENU = "main_menu";
>         protected static final String SEARCH_PANEL = "search_panel";
>
>         static {
>                 Arrays.sort(ALLOWED_PICTURES_TYPES);
>         }
>
>         protected transient Category category;
>
>         private transient Label categoryTreePanel;
>
>         private transient Menu menu;
>
>         public CommonWebPage(PageParameters pageParameters) {
>                 super();
>                 loginUserIfRemembered();
>                 if(pageParameters.get(CATEGORY_PARAMETER) != null) {
>                         category =
> categoryDAO.getCategoryById(Integer.parseInt((String)
> pageParameters.get(CATEGORY_PARAMETER)));
>                 }
>                 menu = new Menu(MAIN_MENU, category, isUserLogin());
>                 add(menu);
>                 categoryTreePanel = new CategoryTreePanel(CATEGORIES,
> categoryDAO.getRootCategories(), category);
>                 add(categoryTreePanel);
>         }
> ....
> }
>
> This is first problem large data is kept in session which is same for
> all users (TreeModel), what can be done? What is wrong?
>
> Second problem is with serializing some objects which we don't want
> and use LoadebaleDeatachableModel for them:
> public class CarPartDataProvider implements IDataProvider{
>
>         private transient CarPartService carPartService;
>
>         private transient Category category;
>
>         public CarPartDataProvider(CarPartService carPartService) {
>                 super();
>                 this.carPartService = carPartService;
>         }
>
>         public CarPartDataProvider(CarPartService carPartService, Category
> category) {
>                 super();
>                 this.carPartService = carPartService;
>                 this.category = category;
>         }
>
>         @SuppressWarnings("unchecked")
>         @Override
>         public Iterator iterator(int first, int count) {
>                 return carPartService.getCarParts(category, first,
> count).iterator();
>         }
>
>         @Override
>         public IModel model(Object carPart) {
>                 return new CarPartDetachableModel((CarPart) carPart);
>         }
>
>         class CarPartDetachableModel extends LoadableDetachableModel {
>
>                 private Integer carPartId;
>
>                 public CarPartDetachableModel(CarPart carPart) {
>                         this.carPartId = carPart.getId();
>                 }
>
>                 @Override
>                 protected Object load() {
>                         return
> carPartService.getCarPartById(this.carPartId);
>                 }
>         }
>
>         @Override
>         public int size() {
>                 return carPartService.getCarPartsSize(category);
>         }
>
>         @Override
>         public void detach() {
>         }
>
>         public CarPartService getCarPartService() {
>                 return carPartService;
>         }
>
>         public void setCarPartService(CarPartService carPartService) {
>                 this.carPartService = carPartService;
>         }
>
>         public Category getCategory() {
>                 return category;
>         }
>
>         public void setCategory(Category category) {
>                 this.category = category;
>         }
>
> }
> I have see CarPart objects in serialized form in sesion which is
> really unwanted for us - we cache all the objects in Hibernate so we
> can get them really fast, serialization is not we want. Also we have
> problem witch web spiders - spiders do not use session so for each
> request is generated new session :(
> I think it's problem by our side, so we ask for little help with
> optimizing.
>
> Best regards,
> Adr
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>


-- 
Aladejebi Ayodeji A.,
DabarObjects Solutions
Phone: +234 9 481 7 156
Mobile: +234 803 589 1780
Email: [EMAIL PROTECTED]
Web: www.dabarobjects.com
Blog: blog.dabarobjects.com

Participate, Collaborate, Innovate
Join Community:
http://www.cowblock.net/

Get A Free Blog:
http://blogs.cowblock.net/

Reply via email to