OutOfMemoryError PermGen space 改大MaxPermSize无法解决,求

bluell 2011-08-03 04:40:58
现在我在学HIBERNATE框架,但是遇到一个棘手的问题,就是OutOfMemoryError PermGen space

我现在程序只用了STRUTS和HIBERNATE,没用SPRING,就老是OutOfMemoryError PermGen space,那再加SPRING就根本不能用了嘛T T

有点语无伦次,抱歉。。
目前的情况是:我家里1G内存的电脑跑起来一点没问题,而且速度也很快,但是单位2G的电脑却老是溢出

我在configure tamcat→JAVA→java options最后加入-XX:PermSize=512M -XX:MaxNewSize=2048m -XX:MaxPermSize=1024m,我觉得我已经加得很大了,虽然好了点,但是还是溢出

然后,每个DAO的方法最后我都flush clear了,还是溢出,求高手指教

PS:不考虑换JDK
...全文
589 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
bluell 2011-08-08
  • 打赏
  • 举报
回复
经过几天的测试与观察,问题解决,结贴~( ̄ˇ ̄)~
chang1984024 2011-08-05
  • 打赏
  • 举报
回复
就是 tomcat的问题 阔一下空间就闷问题了
PermGen space的全称是Permanent Generation space,是指内存的永久保存区域OutOfMemoryError: PermGen space从表面上看就是内存益出,解决方法也一定是加大内存。说说为什么会内存益出:这一部分用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域,它和和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。这种错误常见在web服务器对JSP进行pre compile的时候。

改正方法:-Xms256m -Xmx256m -XX:MaxNewSize=256m -XX:MaxPermSize=256m

我以前碰到过 还可以去注册表改 就看你的tomcat是如何启动的了 去百度搜一下 有更具体的解决办法

bluell 2011-08-05
  • 打赏
  • 举报
回复
问题解决~( ̄ˇ ̄)~
重装了MYECLIPSE和汤姆猫就好了。。。。。不知为何
不过我原来MYECLIPSE更新到了9.1,现在回到9.0了,也许是版本问题吧。。。。。
bluell 2011-08-05
  • 打赏
  • 举报
回复
TO ace62:并不是这样的,单位的机器一样经常重启,因为我只是在本地做测试,SERVER也在本地,数据库是MYSQL

TO ajun_studio:-Xms1600m -Xmx1600m -XX:PermSize=128M -XX:MaxNewSize=512m -XX:MaxPermSize=256m,这是我现在的设置,SQL里面没有用递归

TO liutianxiong888:我承认这个确实是在回避问题,但是CONNECTION我都有关闭的,请看仔细。我觉得问题点还是在于HIBERNATE,就是一直找不到问题到底出在哪里
bluell 2011-08-04
  • 打赏
  • 举报
回复
TO yandu:如何清理项目,谢谢
TO trocp:我估计不是这个问题,因为我一开机启动项目后,就会卡在订单读取那个查询语句那里,就是List<?> orders=se.createQuery("from Orders orders where orders.uname='"+uname+"'").list();这句,我都怀疑我是不是有死循环了,查了N久都觉得程序没有问题,偶尔这句过了,那么在测试下一个页面的时候就会溢出这样,还有,是不是可以手动清理GC这块内存呢,求具体操作
bluell 2011-08-04
  • 打赏
  • 举报
回复
…………疯了。。
我本来想输出sql语句看看,没想到还没输出sql语句就溢出了。。。
oO临时工Oo 2011-08-04
  • 打赏
  • 举报
回复
如果仅仅在热发布(比如开发时,eclipse修改类后,tomcat自动重启)的时候出现这个问题,没多大关系。这个我也遇到。

在JVM堆中有一块内存是不会被GC检查的。

在上面现象中,出现这个问题最可能的原因是:因为每次重启后,JVM堆中总有一些对象永久存在,而动态加载后,这些被修改的类又会被重新加载。造成堆溢出。

yandu 2011-08-04
  • 打赏
  • 举报
回复
重启开发工具...或清理项目.......谢谢
小绵羊 2011-08-04
  • 打赏
  • 举报
回复
订单表是不是关联了很多其他表,如果是的话试着把级联加载改成lazy
Spring89 2011-08-04
  • 打赏
  • 举报
回复
XX:PermSize=512M -XX:MaxNewSize=2048m -XX:MaxPermSize=1024m
不能总以它来解决内存溢出吧?你这不叫解决问题,而是叫回避问题!
你贴的那么多代码为什么ResultSet 、PreparedStatement 、Connection 都没有关闭呢?
这就是个严重问题!
bluell 2011-08-04
  • 打赏
  • 举报
回复
还有个问题,我看了论坛里一些关于溢出的帖子,看到个很神奇的回答
http://topic.csdn.net/u/20100511/11/309fbcd2-3ab9-43eb-99c6-44e51c0d0b9f.html
“这个问题我也遇见过,但是我遇见的比较诡异,找了好长时间没发现代码有什么问题,最后将一些多余的空行给删了去竟然好了!可能是空行中包含了中文全角还是半角空格吧。这是我上次出错时发现的问题,楼主可以参考下。”
虽然我觉得没啥关系,但是我的订单列表页面为了排版好看,所以用了很多空行= =
所以也贴出JSP代码,供参考,望高手指教:


<div class="myorders_content">
<ul>
<logic:equal value="1" name="I">
<li class="order_list1">${ORDER.oid}</li>
</logic:equal>
<logic:notEqual value="1" name="I">
<li class="order_list1"> </li>
</logic:notEqual>
<li class="h_spacing30"> </li>
<li class="order_list2">
<a href="product_detail.jsp?ptid=${PRODUCT.ptid}&pid=${PRODUCT.pid}">${PRODUCT.pename} ><br />${PRODUCT.pcname}</a>
</li>
<li class="h_spacing30"> </li>
<li class="order_list3">¥ ${PRODUCT.pprice}</li>
<li class="h_spacing30"> </li>
<li class="order_list4">${ORDER_DETAIL.odamount}</li>
<li class="h_spacing30"> </li>
<li class="order_list5">¥ ${ORDER_DETAIL.odtotalprice}</li>
<li class="h_spacing30"> </li>
<li class="order_list6">${ORDER.otime}</li>
<li class="h_spacing30"> </li>
<logic:equal value="0" name="ORDER" property="ostatus">
<li class="order_list7">等待发货</li>
</logic:equal>
<logic:equal value="1" name="ORDER" property="ostatus">
<li class="order_list7">等待收货 <a href="#">确认</a></li>
</logic:equal>
<logic:equal value="2" name="ORDER" property="ostatus">
<li class="order_list7">交易成功</li>
</logic:equal>
</ul>
<div class="spacing0"></div>
</div>

bluell 2011-08-04
  • 打赏
  • 举报
回复
确实,我现在因为数据量不大,用的都是全查询,但是,我觉得也不至于到溢出的地步,因为我数据最多的一个表才30条数据,而且这个表没用过全查询

还有就是,我在初期写这个项目的时候因为还没有学HIBERNATE,所以数据库代码都是自己写的,后来的几个表才用HIBERNATE,和这个有关吗?

反正是学校的作业,贴出代码也无所谓,目前我数据库操作的代码大致都在这里了,数据库里面基本没有数据,都是3-5条这样,就产品表是30条
基本上溢出都在读取订单那里,那里涉及3个表,产品表的字段较多,但是只是单条查询而已,而且没有用框架。但是如果那里没有溢出,下一个页面就会溢出,所以我想问题还是出在那里吧


private static ResultSet findData(String sql) {
ResultSet rs=null;
try {
Statement st=conn.createStatement();
rs=st.executeQuery(sql);
} catch (Exception err) {
err.printStackTrace();
}
return rs;
}
public static Users getUser(String uemail) {
Connection conn=getConn();
ResultSet rs=findData("SELECT * FROM users WHERE uemail='"+uemail+"'");
Users user=new Users();
try {
while (rs.next()) {
user.setUid(rs.getInt("uid"));
user.setUname(rs.getString("uname"));
user.setUpsd(rs.getString("upsd"));
user.setUemail(rs.getString("uemail"));
user.setUhint(rs.getString("uhint"));
}
conn.close();
} catch (Exception err) {
err.printStackTrace();
}
return user;
}
public static Product getProduct(int pid) {
Connection conn=getConn();
ResultSet rs=findData("SELECT * FROM product WHERE pid="+pid);
Product product=new Product();
try {
while (rs.next()) {
product.setPid(pid);
product.setPtid(rs.getInt("ptid"));
product.setPename(rs.getString("pename"));
product.setPcname(rs.getString("pcname"));
product.setPprice(rs.getDouble("pprice"));
product.setPstock(rs.getInt("pstock"));
product.setPcapacity(rs.getInt("pcapacity"));
product.setPintro(rs.getString("pintro"));
product.setPdetail(rs.getString("pdetail"));
product.setPmethod(rs.getString("pmethod"));
product.setPimg(rs.getString("pimg"));
}
conn.close();
} catch (Exception err) {
err.printStackTrace();
}
return product;
}
public static List<Users> getUsers() {
Connection conn=getConn();
ResultSet rs=findData("SELECT * FROM users");
List<Users> users=new ArrayList<Users>();
try {
while (rs.next()) {
Users user=new Users();
user.setUid(rs.getInt("uid"));
user.setUname(rs.getString("uname"));
user.setUpsd(rs.getString("upsd"));
user.setUemail(rs.getString("uemail"));
user.setUhint(rs.getString("uhint"));
users.add(user);
}
conn.close();
} catch (Exception err) {
err.printStackTrace();
}
return users;
}
public static List<ProductType> getProductTypes() {
Connection conn=getConn();
ResultSet rs=findData("SELECT * FROM product_type");
List<ProductType> productTypes=new ArrayList<ProductType>();
try {
while (rs.next()) {
ProductType productType=new ProductType();
productType.setPtid(rs.getInt("ptid"));
productType.setPtname(rs.getString("ptname"));
productType.setPttitleimg(rs.getString("pttitleimg"));
productType.setPtdescription(rs.getString("ptdescription"));
productTypes.add(productType);
}
conn.close();
} catch (Exception err) {
err.printStackTrace();
}
return productTypes;
}
public static List<Product> getProducts(int ptid) {
Connection conn=getConn();
ResultSet rs=findData("SELECT * FROM product WHERE ptid="+ptid);
List<Product> products=new ArrayList<Product>();
try {
while (rs.next()) {
Product product=new Product();
product.setPid(rs.getInt("pid"));
product.setPtid(rs.getInt("ptid"));
product.setPename(rs.getString("pename"));
product.setPcname(rs.getString("pcname"));
product.setPprice(rs.getDouble("pprice"));
product.setPstock(rs.getInt("pstock"));
product.setPcapacity(rs.getInt("pcapacity"));
product.setPintro(rs.getString("pintro"));
product.setPdetail(rs.getString("pdetail"));
product.setPmethod(rs.getString("pmethod"));
product.setPimg(rs.getString("pimg"));
products.add(product);
}
conn.close();
} catch (Exception err) {
err.printStackTrace();
}
return products;
}
public static List<Cart> getCarts(String uname) {
Connection conn=getConn();
ResultSet rs=findData("SELECT * FROM cart WHERE uname='"+uname+"'");
List<Cart> carts=new ArrayList<Cart>();
try {
while (rs.next()) {
Cart cart=new Cart();
cart.setCid(rs.getInt("cid"));
cart.setUname(rs.getString("uname"));
cart.setPid(rs.getInt("pid"));
cart.setCamount(rs.getInt("camount"));
cart.setCtotalprice(rs.getDouble("ctotalprices"));
carts.add(cart);
}
conn.close();
} catch (Exception err) {
err.printStackTrace();
}
return carts;
}
public static List<?> getOrders(String uname) {
Session se=HibernateSessionFactory.getSession();
List<?> orders=se.createQuery("from Orders orders where orders.uname='"+uname+"'").list();
se.clear();
se.close();
return orders;
}
public static List<?> getOrderDetails(String oid) {
Session se=HibernateSessionFactory.getSession();
String hql="from OrderDetails orderDetails where orderDetails.oid='"+oid+"'";
List<?> orderDetails=se.createQuery(hql).list();
se.clear();
se.close();
return orderDetails;
}

/**注册*/
public static int addUser(Users user) {
Connection conn=getConn();
List<Users> users=getUsers();
Iterator<Users> iter=users.iterator();
while (iter.hasNext()) {
Users oldUser=iter.next();
if (oldUser.getUname().equals(user.getUname())) {
return 1; //用户名已存在
}
if (oldUser.getUemail().equals(user.getUemail())) {
return 2; //电子邮箱已存在
}
}
String sql="INSERT users VALUES(null,?,?,?,?)";
try {
PreparedStatement pst=conn.prepareStatement(sql);
pst.setString(1, user.getUname());
pst.setString(2, user.getUpsd());
pst.setString(3, user.getUemail());
pst.setString(4, user.getUhint());
pst.executeUpdate();
conn.close();
} catch (Exception err) {
err.printStackTrace();
return -1; //其它错误,注册失败
}
return 0; //注册成功
}

/**登录*/
public static int isLogin(String uemail,String upsd) {
String sql="SELECT * FROM users WHERE uemail=?";
Connection conn=getConn();
try {
PreparedStatement pst=conn.prepareStatement(sql);
pst.setString(1, uemail);
ResultSet rs=pst.executeQuery();
if (rs.next()) {
if (!rs.getString("upsd").equals(upsd)) {
return 2; //密码错误
}
} else {
return 1; //用户名错误
}
conn.close();
} catch (Exception err) {
err.printStackTrace();
return -1; //登录失败
}
return 0; //登录成功
}

/**加入购物袋*/
public static int addCart(String uname,int pid) {
double pprice=getProduct(pid).getPprice();
Connection conn=getConn();
ResultSet rs=findData("SELECT * FROM cart WHERE uname='"+uname+"' AND pid="+pid);
try {
if (rs.next()) {
String sql="UPDATE cart SET camount=?,ctotalprices=? WHERE uname=? AND pid=?";
int camount=rs.getInt("camount")+1;
PreparedStatement pst=conn.prepareStatement(sql);
pst.setInt(1, camount);
pst.setDouble(2, camount*pprice);
pst.setString(3, uname);
pst.setInt(4, pid);
pst.executeUpdate();
conn.close();
return 1; //已有此商品,更新数量
} else {
String sql="INSERT INTO cart VALUES(null,?,?,?,?)";
PreparedStatement pst=conn.prepareStatement(sql);
pst.setString(1, uname);
pst.setInt(2, pid);
pst.setInt(3, 1);
pst.setDouble(4, pprice);
pst.executeUpdate();
conn.close();
return 2; //新加入购物袋的商品
}
} catch (Exception err) {
err.printStackTrace();
return 0;
}
}

/**从购物袋移出*/
public static boolean delCart(int cid) {
Connection conn=getConn();
String sql="DELETE FROM cart WHERE cid=?";
try {
PreparedStatement pst=conn.prepareStatement(sql);
pst.setInt(1, cid);
pst.executeUpdate();
conn.close();
} catch (Exception err) {
err.printStackTrace();
return false;
}
return true;
}

/**统计购物袋商品总数*/
public static int cartCount(String uname) {
Connection conn=getConn();
ResultSet rs=findData("SELECT COUNT(*) FROM cart WHERE uname='"+uname+"'");
int count=0;
try {
while (rs.next()) {
count=rs.getInt("COUNT(*)");
}
conn.close();
} catch (Exception err) {
err.printStackTrace();
}
return count;
}

/**下订单*/
public static void addOrder(Orders order,List<OrderDetails> orderDetails) {
Session se=HibernateSessionFactory.getSession();
Transaction tran=se.beginTransaction();
se.save(order);
Iterator<OrderDetails> iter=orderDetails.iterator();
while (iter.hasNext()) {
OrderDetails orderDetail=iter.next();
se.save(orderDetail);
}
List<?> carts=se.createQuery("from Cart cart where cart.uname='"+order.getUname()+"'").list();
Iterator<?> iterCarts=carts.iterator();
while (iterCarts.hasNext()) {
se.delete(iterCarts.next());
}
se.flush();
se.clear();
tran.commit();
se.close();
}

/**添加地址*/
public static void addAddress(Address address) {
Session se=HibernateSessionFactory.getSession();
Transaction tran=se.beginTransaction();
se.save(address);
se.flush();
se.clear();
tran.commit();
se.close();
}
/**统计地址总数*/
public static int addressCount(String uname) {
Session se=HibernateSessionFactory.getSession();
Query qu=se.createQuery("select count(*) from Address address where address.uname='"+uname+"'");
int count=(Integer)qu.uniqueResult();
se.clear();
se.close();
return count;
}
飓风zj 2011-08-04
  • 打赏
  • 举报
回复
看看你写代码时候么有释放资源之类的
-Xms512m -Xmx512m -XX:PermSize=512M -XX:MaxPermSize=512M 这样设置试试吧
-Xms512m -Xmx512m这两个是设置堆内存的,最好设置一样大,以防止jvm进行频繁的调整。

还有你sql查询的是什么?有递归没?
ace62 2011-08-04
  • 打赏
  • 举报
回复
单位的机器是启动后就一直运行吗,自己的机器由于经常重新启动,特别是Tomcat,所以内存的问题没有暴露出来
还有一点,数据库Server在什么机器上,用的是什么数据库?SQLServer默认不释放内存,将可能导致计算机没有更多内存分配给Tomcat,这时你设置的再大也没用
bluell 2011-08-04
  • 打赏
  • 举报
回复
我重启MYECLIPSE,然后终于过了那个查询语句,一共才4个语句,输出如下:

Hibernate: select orders0_.oid as oid1_, orders0_.uname as uname1_, orders0_.oprice as oprice1_, orders0_.otime as otime1_, orders0_.ostatus as ostatus1_ from lamer.orders orders0_ where orders0_.uname='user'
Hibernate: select orderdetai0_.odid as odid0_, orderdetai0_.oid as oid0_, orderdetai0_.pid as pid0_, orderdetai0_.odamount as odamount0_, orderdetai0_.odtotalprice as odtotalp5_0_ from lamer.order_details orderdetai0_ where orderdetai0_.oid='LM1312251487505'
Hibernate: select orderdetai0_.odid as odid0_, orderdetai0_.oid as oid0_, orderdetai0_.pid as pid0_, orderdetai0_.odamount as odamount0_, orderdetai0_.odtotalprice as odtotalp5_0_ from lamer.order_details orderdetai0_ where orderdetai0_.oid='LM1312259587630'
Hibernate: select orderdetai0_.odid as odid0_, orderdetai0_.oid as oid0_, orderdetai0_.pid as pid0_, orderdetai0_.odamount as odamount0_, orderdetai0_.odtotalprice as odtotalp5_0_ from lamer.order_details orderdetai0_ where orderdetai0_.oid='LM1312260627380'

然后我点击其它页面,就华丽丽地溢出了= =
小绵羊 2011-08-03
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 longq121 的回复:]

查询多大的数据造成内存溢出,不太可能啊,如果说hibernate配置缓存有问题,但如果不是一次行内存溢出,jVM会自动清除的
[/Quote]
hibernate把数据库里的数据全部实例化成对象了,要是字段多的话很容易就爆了
longq121 2011-08-03
  • 打赏
  • 举报
回复
查询多大的数据造成内存溢出,不太可能啊,如果说hibernate配置缓存有问题,但如果不是一次行内存溢出,jVM会自动清除的
小绵羊 2011-08-03
  • 打赏
  • 举报
回复
一般是hibernate查询时数量过多造成的内存溢出。
尽量不要用全查询,用分页查询来代替
bluell 2011-08-03
  • 打赏
  • 举报
回复
我说的楼上是:x19881216
bluell 2011-08-03
  • 打赏
  • 举报
回复
不是很明白楼上的意思,并求如何释放内存
加载更多回复(6)

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧