`

hibernate scroll 和 list

阅读更多
原文:https://forum.hibernate.org/viewtopic.php?p=2386803





Hi, I've written a small test to measure the memory consumption of my Hibernate code. It seem that getting a List of objects with the list() method of a Query uses much more memory than creating the List manually by using a ScrollableResult.

The ScrollableResult memory consumption is almost identical to the consumption of a pure JDBC implementation. The list() memory consumption needs much more MB. In my case with my Database 50.000 Object need approximately 13 MB with ScrollableResult and 23 MB with list()!!

Can anybody explain this behaviour? Is my code wrong?

Hibernate Version: 3.2.2ga
Windows XP SP2
Database: Oracel 10g

Testcode:
Note: You have to replace the HQL Query with your Hibernate Objects!


Code:

public class HibernateMemoryConsumptionTest extends TestCase {

   private int size = 50000;

   private int repeats = 2;

   private boolean trackMemoryConsumption = true;

   private Runtime runtime;

   protected void setUp() throws Exception {
      super.setUp();
      runtime = Runtime.getRuntime();
   }

   protected void tearDown() throws Exception {
      super.tearDown();
      runtime = null;
   }

   public void testHibernateWithOneSession() {
      // init
      HibernateUtil.getSessionFactory();
      long heap1 = 0;
      long heap2 = 0;

      long start = System.currentTimeMillis();

      StatelessSession session = null;
      Transaction tx = null;
      List results = null;
      try {
         session = HibernateUtil.getSessionFactory().openStatelessSession();

         for (int i = 0; i < repeats; i++) {
            if (trackMemoryConsumption) {
               System.err
                     .println("Note: Memory measurement can influence time measurement!");
               runGC();
               heap1 = usedMemory(); // Take a before heap snapshot
            }

            tx = session.beginTransaction();
            Query query = session
                  .createQuery("FROM Cashflow ");
            query.setFirstResult(1);
            query.setMaxResults(size);
            results = query.list();
            tx.commit();

            assertEquals(size, results.size());

            if (trackMemoryConsumption) {
               heap2 = usedMemory(); // Take an after heap snapshot:
               final long heapsizeDiff = heap2 - heap1;
               System.out.println("'before' heap: " + heap1
                     + ", 'after' heap: " + heap2);
               System.out.println("heap delta: " + heapsizeDiff / 1024d
                     / 1024d + " MB");
            }

            results = null;

            runGC();// aufräumen für nächste schleife

         }
      } catch (Throwable t) {
         t.printStackTrace();
         if (tx != null) {
            tx.rollback();
         }
         throw new PersistenceException(t);
      }

      long end = System.currentTimeMillis();

      System.out.println("runtime with list() "
            + repeats + " repeats with " + size + " Cashflows = "
            + ((end - start) / (double) repeats));
   }

   public void testHibernateWithScrollableResult() {
      // init wird nicht mitgezählt!
      HibernateUtil.getSessionFactory();
      long heap1 = 0;
      long heap2 = 0;

      long start = System.currentTimeMillis();

      StatelessSession session = null;
      Transaction tx = null;
      ScrollableResults results = null;
      List cashFlows = null;
      try {
         session = HibernateUtil.getSessionFactory().openStatelessSession();

         for (int i = 0; i < repeats; i++) {
            cashFlows = new ArrayList();
            if (trackMemoryConsumption) {
               System.err.println("Note: Memory measurement can influence time measurement!");
               runGC();
               heap1 = usedMemory(); // Take a before heap snapshot
            }

            tx = session.beginTransaction();
            Query query = session
                  .createQuery("FROM Cashflow ");
            query.setFirstResult(1);
            query.setMaxResults(size);

            results = query.scroll(ScrollMode.FORWARD_ONLY);

            while (results.next()) {
               cashFlows.add(results.get(0));
            }
            tx.commit();

            assertEquals(size, cashFlows.size());

            if (trackMemoryConsumption) {
               heap2 = usedMemory(); // Take an after heap snapshot:
               final long heapsizeDiff = heap2 - heap1;
               System.out.println("'before' heap: " + heap1
                     + ", 'after' heap: " + heap2);
               System.out.println("heap delta: " + heapsizeDiff / 1024d
                     / 1024d + " MB");
            }

            results = null;
            cashFlows = null;

            runGC();// aufräumen für nächste schleife

         }
      } catch (Throwable t) {
         t.printStackTrace();
         if (tx != null) {
            tx.rollback();
         }
         throw new PersistenceException(t);
      }

      long end = System.currentTimeMillis();

      System.out.println("runtime with ScrollableResults "
            + repeats + " repeats with " + size + " Cashflows = "
            + ((end - start) / (double) repeats));
   }

   private void runGC() throws Exception {
      // It helps to call Runtime.gc()
      // using several method calls:
      for (int r = 0; r < 4; ++r)
         _runGC();
   }

   private void _runGC() throws Exception {
      long usedMem1 = usedMemory(), usedMem2 = Long.MAX_VALUE;
      for (int i = 0; (usedMem1 < usedMem2) && (i < 500); ++i) {
         runtime.runFinalization();
         runtime.gc();
         Thread.currentThread().yield();

         usedMem2 = usedMem1;
         usedMem1 = usedMemory();
      }
   }

   private long usedMemory() {
      return runtime.totalMemory() - runtime.freeMemory();
   }
}
分享到:
评论

相关推荐

    Hibernate 多表连接分页查询示范项目

    6. **执行查询**:调用 list() 或 scroll() 方法执行查询,获取结果集。 7. **处理结果**:遍历查询结果,将数据绑定到视图或者进一步处理。 总结,"Hibernate 多表连接分页查询示范项目"是一个实用的示例,它展示...

    Hibernate中的query 分页.doc

    本文将探讨Hibernate中两种主要的分页方式:`query.scroll()`和使用`query.setFirstResult(), query.setMaxResults()`。 首先,`query.scroll()`方法基于JDBC 2.0的可滚动结果集实现。这种方式允许应用程序在结果...

    hibernate分页查询 数据库连接

    最后,通过`list()`或`scroll()`方法执行查询并获取结果集: ```java Query query = session.createQuery(hql); query.setParameter("value", someValue); query.setFirstResult(start); query.setMaxResults(count...

    hibernate--3.Hibernate数据持久化(通过 Session 操纵对象)

    总的来说,Hibernate的Session接口提供了一套完整的对象持久化和数据库操作机制,使得开发者能够以面向对象的方式处理数据,极大地提高了开发效率和代码的可读性。通过深入理解和熟练运用Session,可以轻松地在Java...

    在JDBC,hibernate中实现分页

    ### 在JDBC与Hibernate中实现分页功能 随着数据量的不断增长,...通过上述介绍可以看出,无论是使用Hibernate还是JDBC,合理设计和实现分页功能能够显著提升用户界面的性能和响应速度,同时也提高了系统的整体性能。

    hibernate api 中文

    Query接口提供了执行HQL查询的方法,如`createQuery()`, `list()`, `scroll()`, `executeUpdate()`等。 三、Hibernate注解 1. @Entity:标记一个类为实体类,对应数据库中的表。 2. @Table:定义实体对应的数据库...

    hibernate分页查询

    Hibernate分页查询基于SQL的LIMIT和OFFSET子句,通过Session的createQuery或createSQLQuery方法创建查询,并设置FirstResult和MaxResults属性来实现分页。FirstResult表示从结果集的第几个元素开始获取,MaxResults...

    hibernate将本地SQL查询结果封装成对象(最终).zip

    - 结果集转换:`addEntity()`方法用于指定查询结果应被映射到哪个实体类,`list()`或`scroll()`方法执行查询并返回结果集,这些结果集将自动封装为对应的Java对象。 5. 示例: 假设我们有一个`User`实体类,对应...

    hibernate中实现真分页和假分页技术

    本文将详细讲解如何在Hibernate中实现真分页(物理分页)和假分页(逻辑分页)。 首先,我们来了解什么是真分页和假分页。假分页,也称为内存分页,它一次性加载所有数据到内存中,然后通过索引进行分页显示,这种...

    hibernate经典分页源代码

    Hibernate 提供了 Criteria API 和 HQL(Hibernate Query Language)来实现分页查询。 2. Hibernate Criteria API 分页: Hibernate 的 Criteria API 允许开发者以面向对象的方式构建动态查询。要实现分页,可以...

    Hibernate持久化映射一对多和多对一

    本文将深入探讨Hibernate中的两个重要概念:一对多(One-to-Many)和多对一(Many-to-One)的持久化映射。 ### 一对多映射 **定义**: 一对多映射表示一个实体(如部门)可以关联多个实体(如员工)。在数据库层面...

    Hibernate-HQL.rar_HQL_hibernate hql

    在Hibernate中,通过Session对象的createQuery或createSQLQuery方法创建HQL查询,然后调用list、uniqueResult、scroll等方法执行查询。执行过程中,Hibernate会自动进行类型转换和结果集的封装,极大地降低了开发...

    hibernate 实现分页

    4. 调用`list()`或`scroll()`方法执行查询,返回结果集。 示例代码: ```java Session session = sessionFactory.openSession(); Criteria criteria = session.createCriteria(YourEntity.class); criteria....

    hibernate教程

    3. **检索**: `Session`的`get()`、`load()`方法获取单个实体,`list()`, `scroll()`, `iterate()`用于查询结果集。 4. **删除**: 使用`Session`的`delete()`方法删除实体。 5. **事务处理**: 在事务边界内执行...

    hibernate分页

    Hibernate提供了SQL风格的Query接口,可以通过setFirstResult()和setMaxResults()方法实现分页。setFirstResult()设置从哪一条记录开始,setMaxResults()指定最多返回多少条记录。例如: ```java Session ...

    hibernate-search-4.1.0.CR2-dist

    4. **结果处理**:获取查询结果后,可以通过List、Scroll或EntityResult进行处理。 总结,Hibernate Search 4.1.0.CR2是Java开发中实现高效全文搜索的强大工具。通过深入理解和熟练运用其特性,开发者可以构建出...

    关于Struts+Hibernate分页的例子

    在分页场景中,Hibernate提供了Criteria、HQL(Hibernate Query Language)以及Session的分页方法,如`scroll()`和`list()`,来实现数据的分页获取。 在分页实现过程中,我们需要考虑以下几个关键点: 1. **分页...

    hibernate分页技术

    总的来说,Hibernate提供的分页技术使得开发者能够灵活地处理数据分页,同时考虑到性能和用户体验。在实际开发中,根据项目需求和数据规模,选择最适合的分页策略是非常重要的。通过熟练掌握和运用这些分页技术,...

    只进结果集不支持请求的操作的“解决方法

    在数据库操作中,有时会遇到一些异常情况,比如尝试对一个不支持滚动(scroll)或某些特定操作的结果集进行操作时,系统可能会抛出异常。本篇文章将针对此类问题提供详细的解决方案,并通过分析具体的异常堆栈信息来...

    com.microsoft.sqlserver.jdbc.SQLServerException: 只进结果集不支持请求的操作 解决方案

    这可以通过在Hibernate配置文件中设置`hibernate.connection.autocommit`属性为`false`,并在查询前手动设置事务,然后通过`Session`的`createSQLQuery()`或`createQuery()`方法附加`ResultSet.TYPE_SCROLL_...

Global site tag (gtag.js) - Google Analytics