解决方案 »

  1.   

    jvm的原理年老代堆空间被占满(年老代存放从年轻代存活的对象。一般来说年老代存放的都是生命期较长的对象。)
    异常: java.lang.OutOfMemoryError: Java heap space
    持久代被占满
    异常:java.lang.OutOfMemoryError: PermGen space 
    主要原因就是大量动态反射生成的类不断被加载,最终导致Perm区被占满。
    堆栈溢出
    异常:java.lang.StackOverflowError
    说明:这个就不多说了,一般就是递归没返回,或者循环调用造成
    线程堆栈满
    异常:Fatal: Stack size too small
    系统内存被占满
    异常:java.lang.OutOfMemoryError: unable to create new native thread 
    这里看不到你的图,大胆推测一下,能提出这个问题的人肯定是对java的堆栈是有了解的并且是对的。所以我猜测session中的insert其实已经把数据放到事务中了,也就是已经交给数据库了,而commit只是让数据库执行一下而已。这个时候已经不再占用java内存了,所以不会报错。
    我没看过mybatis源码,不过我依据hibernate冒昧猜测的。
      

  2.   

    应该说依据现象猜测,因为我也没有看过hibernate源码,没有用过mybatis,也是通过现象猜测
      

  3.   

    try {
    for(int i=1;i<1000007;i++){
    Person person=new Person();
    person.setName("batName"+i);
    pList.add(person);
    }
    改成:
    try {
    Person person=null;
    for(int i=1;i<1000007;i++){
    person=new Person();
    person.setName("batName"+i);
    pList.add(person);
    }
    哈哈,最近在研究java基础,确实收获不小啊与楼主共勉吧
      

  4.   

    别把你对Java内存的理解套到数据库上,除非你那数据库是Java自己的内存数据库。在事务未提交之前,所有的sql语句数据应该都在session中,对吧?
    扯淡。未提交之前数据已经写入了数据库的数据文件中,提交这个动作只不过是做个标记,标记这些块是“真正的数据块”,回滚这个动作只不过是告诉数据库这些块是“可以写入数据的空白块”
      

  5.   

    我猜想也是不会总在jvm内存空间中的,否则我的实验中早该溢出。那你知道未提交事务之前,这些数据具体跑到数据库哪里了吗?你说已经写到数据文件中,具体是值哪文件?我在进行大量的批量session.insert()过程中,检测过mysql中的与被插入数据的表同名的frm文件,发现大小并不发生变化。你说事务未提交之前就已经将数据写入数据库了,那么如果后续发生错误,事务如何回滚的,是将数据库状态恢复到之前的状态吗?如果真是这样,那么来回这么一折腾,数据库的效率岂不是太低了。如果你有耐心就讲细点,或者告诉到什么地方看针对性的资料也可,谢谢。
      

  6.   

    多数人都说是在session.insert()批量插入大量数据的时候,已将数据写入数据库,推测来看,这样比较合理。但是怎么验证呢?我没找到办法。