TableContainer memory issue

Hi All, we have an Recruitment-System application! application has many tab views, and in one we have table that contains all candidates! Is it possible that container will consume more than 100mb of memory to store about 15, 000 objects?! any help will be highly appreciated=)

Hello,

In order to get the certain answer and possible help - I would suggest you specifying the the type of the container used, brief description of the objects stored (if those have user pix or any other large properties then the size might be quite big) etc.

cheers,
sasha

We extended BeanItemContainer, Candidate model has next fields:



  /** The first name. */
  private String firstName;

  /** The last name. */
  private String lastName;

  /** The gender. */
  private Gender gender = Gender.MALE;

  /** The mobile. */
  private String mobile;

  /** The email. */
  private String email;

  /** The birth year. */
  private Integer birthYear;

  /** The comment. */
  private String comment;

  /** The project. */
  private Project project;

  /** The project. */
  private Location location;

  /** The project. */
  private HighSchool highSchool;

  /** The source. */
  private Source source;

  /** The source. */
  private Position position;

  /** The created by. */
  private User createdBy;

  /** The modified by. */
  private User modifiedBy;

  /** The created. */
  private Date createdDateTime;

  /** The modified. */
  private Date modifiedDateTime;

  /** The candidate histories. */
  private List<CandidateHistory> candidateHistories;

I think that shouldn’t be a huge problem for container, but indeed memory issue exists! also it takes about 20-25 seconds to update container( btw, there is no problem with hibernate cashing or etc.

CandidateContainer:



public class CandidateContainer extends BaseBeanContainer<Candidate> implements Serializable {

  /** The Constant serialVersionUID. */
  private static final long serialVersionUID = 992145450096639873L;

  /** The Constant LOGGER. */
  private static final Logger LOGGER = Logger.getLogger(CandidateContainer.class);

  /** The candidate manager impl. */
  private CandidateManagerImpl candidateManagerImpl;

  /** Natural property order for Person bean. Used in tables and forms. */
  public static final Object[] NATURAL_COL_ORDER = new Object[]
 {"firstName", "lastName", "mobile",
      "location.locationName", "project.projectName", "latestHistory.stage.stageName",
      "latestHistory.assignedTo.fullName", "latestHistory.assignedDateTime",
      "latestHistory.stageResult.resultCategory.resultCategoryName"};

  /** "Human readable" captions for properties in same order as in NATURAL_COL_ORDER. */
  public static final String[] COL_HEADERS_ENGLISH = new String[]
 {Lang.getMessage("first_name"),
      Lang.getMessage("surname"), Lang.getMessage("mobile"), Lang.getMessage("location"),
      Lang.getMessage("project"), Lang.getMessage("stage"), Lang.getMessage("assigned_to"),
      Lang.getMessage("assign_date"), Lang.getMessage("result_category")};

  /**
   * Instantiates a new candidate container.
   */
  public CandidateContainer() {
    super(Candidate.class);
    addNestedContainerProperty("project.projectName");
    addNestedContainerProperty("location.locationName");
    addNestedContainerProperty("latestHistory.stage.stageName");
    addNestedContainerProperty("latestHistory.assignedTo.fullName");
    addNestedContainerProperty("latestHistory.assignedDateTime");
    addNestedContainerProperty("latestHistory.stageResult.resultCategory.resultCategoryName");

    candidateManagerImpl = (CandidateManagerImpl) SpringHandler.getBean("candidateManager");
    //init();
  }

  /**
   * Inits the container with data..
   */
  public void init() {
    List<Candidate> candidates = new ArrayList<Candidate>();
    if (candidateManagerImpl != null) {
      candidates = candidateManagerImpl.getAll();
    } else {
      LOGGER.warn("candidateManager bean are null. Can't take candidates.");
    }
    super.init(candidates);
    sortByDate();
  }
  
  public void sortByDate() {
    fireItemSetChange();
    // sorting table by assigned date (descending)
    sort(new Object[] {"latestHistory.assignedDateTime"}, new boolean[]
 {false});
  }
}

BaseBeanContainer:


public abstract class BaseBeanContainer<POJO> extends BeanItemContainer<POJO> {
  
  /** The Constant serialVersionUID. */
  private static final long serialVersionUID = -980927629019311062L;
  
  /**
   * Instantiates a new banner container.
   *
   * @param type - the type.
   */
  public BaseBeanContainer(final Class<POJO> type) {
    super(type);
  }

  /**
   * Instantiates a new banner container.
   *
   * @param type - the type.
   * @param pojos - the pojos.
   */
  public BaseBeanContainer(final Class<POJO> type, final List<POJO> pojos) {
    super(type);
    init(pojos);
  }

  /**
   * Inits the container with data.
   *
   * @param pojos - the pojos.
   */
  public void init(final List<POJO> pojos) {
    this.removeAllItems();

    if (pojos != null) {
      for (POJO pojo : pojos) {
        this.addItem(pojo);
      }
    }
  }
}

Using BeanItemContainer.addAll(Collection) instead of a loop calling addItem(bean) should be much more efficient for large numbers of items as it does not send unnecessary notifications - especially after the container has been attached to a UI component.

If the container is taking that much memory, that means the data in it is taking memory - each item has some overhead but should not have that much. If the container takes too much memory, I would recommend considering some lazy loading container such as
JPAContainer
(commercial),
Lazy Query Container
or
HbnContainer
.

Henri Sara, Thanks for reply!

This solution increased performence of the application, but problem with memory still remains.

I’m not sure, that implementing others containers will be a good idea, it will cause a lot of alterations( Nevertheless, i’ll look through others containers, but if someone had the same issue, or could reproduce, i would be pleased!
If the problem truly in BeanItemContainer, the only solution is to implement others containers.

You could check how much memory the array of POJOs takes before you add them to the container. That will give you an idea of the overhead in this particular case. Most of the overhead should be in BeanItems and their metadata, not in the container, but testing item by item can be misleading as some of the metadata is shared within the container.

It would also be interesting to hear the numbers - what is the ratio between the amount of memory taken by the POJOs and the total memory taken by the container (before it is attached to a UI component)?

Henri Sara, i’ve just looked through what you asked. So what can i say: i’ve used visualvm to monitor the memory consumption, that wasn’t accurate testing, but what i’ve got is approximately 7-9( i think not a good ratio.

Have anyone tried to reproduce this memory issue?!