java如何减少桌面应用程序中的hibernate内存使用?
我正在开发一个桌面应用程序。我正在使用hibernate 4、带嵌入式驱动程序的JavaDB和JavaFx。但我真的很难用冬眠记忆。下面我提供了我的代码
我在一个名为MODEL_E2B_WORDLIST的数据库表中搜索。我有两种方法
- 冬眠
- JDBC李>
我已经用JDBC和Hibernate运行了大约500次相同的搜索操作。我发现JDBC在这个操作中占用的内存不超过100mb,但Hibernate使用的内存约为400mb
现在我想知道我在hibernate中犯了什么错误,占用了这么多内存,或者hibernate是正常的
CFG:
<hibernate-configuration>
<session-factory>
<!--.Connection Properties.-->
<property name="hibernate.dialect">org.hibernate.dialect.DerbyDialect</property>
<property name="hibernate.connection.driver_class">org.apache.derby.jdbc.EmbeddedDriver</property>
<property name="hibernate.connection.url">jdbc:derby:vocubulary;create=true;</property>
<property name="hibernate.connection.username">app</property>
<property name="hibernate.connection.password">app</property>
<property name="hibernate.show_sql">true</property>
<!--done to test.-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!--<mapping resource="word.hbm.xml"/>-->
<mapping class="com.vocubulary.model.Model_E2B_WordList"/>
</session-factory>
</hibernate-configuration>
DAO Impl类:
public class DAO_e2b_Impl implements DAO_e2b_I
{
SessionFactory factory = HibernateUtil.getSessionFactory();
// Session session = factory.openSession();
@Override
public List dao_e2b_get_wordsList_afterSerach(String e2b_searchKey)
{
// SessionFactory factory = HibernateUtil.getSessionFactory();
Session session = factory.openSession();
List list_word = null;
try
{
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Model_E2B_WordList.class);
criteria.setProjection(Projections.property("e2b_word")); //Projections.property is used to retrieve specific columns
criteria.add(Restrictions.ilike("e2b_word", e2b_searchKey, MatchMode.START));
list_word = criteria.list();
tx.commit();
} catch (Exception e)
{
e.printStackTrace();
} finally
{
session.close();
// factory.close();
System.out.println("\n\n\n Final loadData : all conection closed");
}
return list_word;
// return jdbcDB(e2b_searchKey);
}
}
测试类
@Test
public void search_in_e2b_wordList() throws Exception
{
hibernateTest(500);
// jdbcTest(500);
}
public void hibernateTest(int loopCounter) throws Exception
{
DAO_e2b_Impl dAO_e2b_Impl = new DAO_e2b_Impl();
List l = new ArrayList();
int x = 0;
while (x != loopCounter)
{
l = dAO_e2b_Impl.dao_e2b_get_wordsList_afterSerach("Man");
System.out.println("Size :" + l.size());
x++;
l.clear();
System.out.println("count : " + x);
Thread.sleep(100);//used, to see the effect in the task manager.
}
}
public void jdbcTest(int loopCounter) throws Exception
{
List l = new ArrayList();
int x = 0;
while (x != loopCounter)
{
l = jdbcDB();
System.out.println("Size :" + l.size());
x++;
l.clear();
System.out.println("count : " + x);
Thread.sleep(100);//used, to see the effect in the task manager.
}
}
public List jdbcDB()
{
// JDBC driver name and database URL
String JDBC_DRIVER = "org.hibernate.dialect.DerbyDialect";
String DB_URL = "jdbc:derby:vocubulary;create=true;";
// Database credentials
String USER = "app";
String PASS = "app";
Connection conn = null;
Statement stmt = null;
List l = new ArrayList();
try
{
//STEP 2: Register JDBC driver
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
//STEP 3: Open a connection
System.out.println("Connecting to database...");
conn = DriverManager.getConnection(DB_URL, USER, PASS);
//STEP 4: Execute a query
System.out.println("Creating statement...");
stmt = conn.createStatement();
String sql;
// sql = "SELECT app.MODEL_E2B_WORDLIST.E2B_WORD from app.MODEL_E2B_WORDLIST";
sql = "SELECT app.MODEL_E2B_WORDLIST.E2B_WORD from app.MODEL_E2B_WORDLIST WHERE E2B_WORD LIKE 'MAN%'";
ResultSet rs = stmt.executeQuery(sql);
//STEP 5: Extract data from result set
while (rs.next())
{
//Retrieve by column name
String last = rs.getString("E2B_WORD");
//Display values
// System.out.println("Last: " + last);
l.add(last);
}
//STEP 6: Clean-up environment
rs.close();
stmt.close();
conn.close();
} catch (SQLException se)
{
//Handle errors for JDBC
se.printStackTrace();
} catch (Exception e)
{
//Handle errors for Class.forName
e.printStackTrace();
} finally
{
//finally block used to close resources
try
{
if (stmt != null)
{
stmt.close();
}
} catch (SQLException se2)
{
}// nothing we can do
try
{
if (conn != null)
{
conn.close();
}
} catch (SQLException se)
{
se.printStackTrace();
}//end finally try
}//end try
System.out.println("Goodbye!");
return l;
}
模型类
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Model_E2B_WordList
{
// i used "lombok"
@Id @Getter @Setter
private String e2b_word;
}
# 1 楼答案
Hibernate非常灵活,所以您可以调整它,使其使用的内存量与JDBC变体几乎相同
Hibernate使用
Session
作为一级缓存。您可以尝试使用StatelessSession
来减少使用的内存量。你可以用SessionFactory#openStatelessSession()
打开StatelessSession
你不需要这个
List l = new ArrayList();
在
hibernateTest()
中,由于赋值new ArrayList()
从不使用。通过这种方式分配一个结果