我用JAVA读数据库中某个表的数据,这个表大概有27W条记录,我想一次性都读出来放到Arraylist里面。但总是出现OutOfMemory的异常错误:Exception in thread "Timer-0" Exception in thread "main" java.lang.OutOfMemoryError: Java heap space我设置了eclipse.ini中内存的分配后还是有问题。eclipse.ini的设置:-showsplash
com.genuitec.myeclipse.product
--launcher.XXMaxPermSize
256m
-vmargs
-Xms512m
-Xmx768m
-Duser.language=en 
-XX:PermSize=64M 
-XX:MaxPermSize=256M机器是XP系统,2G内存
请高手不吝赐教啊!

解决方案 »

  1.   

    27w数据放一个List这是不是设计上有问题?
      

  2.   

    这个27W条记录不是要处理的 只是用来查询匹配的 27W条记录是IP库 还有一个IP库有9W条记录 我要通过一个IP地址找到匹配的记录 然后判断这两个库的区别有没有性能比较快 有没有对数据库服务器不会造成太大压力的办法?
      

  3.   

    嘿嘿,减少数据库的压力,也不是通过把java虚拟机整死这样的手段吧?得大家都受得了不是?
    无论谁挂了,都不能得到正确的结果。
    再说,一次1万条,读27次,不至于就把数据库搞死吧?
    还有,你不会频繁的读这27万条数据吧?
      

  4.   

    要匹配何必全捞出来,where后面限定下不行?只捞匹配的不就可以了?
      

  5.   

    现在是每拿到一个IP都要到这27W里面去查的  怎么分开读呢?
      

  6.   

    那你为什么不用sql读呢?
    在数据库里做索引,做view。这样不就快了么
      

  7.   

    27W的数据放到List中,哥们,你真狠哪!!!
      

  8.   


    我晕,数据库压力是小了,但是服务器的压力成批成批地增加了!不要想把 27 万的数据全部塞到内存中,即使是扩大 JVM 内存也是无济于是的,只能治标治不了本的。
      

  9.   

    把频繁使用的数据放入内存中缓冲,你这样做应该没什么不对不过 ,你是每一行重新封装成POJO类再add进list吗?如果这样的话内存不够也太夸张了,27W行,27W*1K=270M ,难道一行生成一个对象,这个对象要1K?
    你的字段都是些啥数据啊?
    再检查检查你的代码吧;应该是其他的问题造成不行debug一下,把生成100个或者1000个的时候的jvm内存打印出来看看;
      

  10.   

    当然,数据量非常大的时候,就不可能这么做了;但不是说放到内存是不对的办法,而是因为数据太大不能放到有限的内存中;27W行数据,对于现在按G来算的内存,应该不是问题我原来做的手机号段,也是这么做的;有17W行数据,每行类似:1388888,北京 ,北京,010;
      

  11.   

    同意,可以考虑精简list中每个对象的复杂程度。
      

  12.   

    你设置了eclipse.ini中内存的分配有什么用呢?应该设置运行时的vm argument
      

  13.   

    不要想一次读取27W条数据,更何况以后这些数据还会增长。
    还有,为什么你会觉得每次读取数据库会影响你的系统速度,你对此有什么依据么?你做过测试,这种影响足以影响到用户体验与系统稳定性么?你不会是想用一个有很明显问题的处理方式来处理一个没有经过任何验证的莫须有的问题吧?
    而且就算你觉得每次都去访问数据库会影响速度,即使那个是真的影响到用户体验与系统稳定性,现在已经有很多现成技术,例如连接池,你的系统有连接池么?不会每次都会打开一个connection吧?你的系统有数据缓存么?每次处理相同数据的时候会不会都会去数据库里面挖数据?
    如果你是在做一个用作生产系统,我对你天真的想法感到遗憾,做系统是需要严谨的,不能跟着感觉走,要测试与验证,也许你担心的问题根本就不是一个问题,而你提出的解决方案本身就是一个问题。
      

  14.   

    一次27w是设计的问题,解决了数据库压力,制造了web服务器压力,得不偿失。
    建议优化数据库,提高数据库响应能力。
    如果IP库是静态的,可以考虑以文件形式存放,人工有针对性的优化存储结构。
      

  15.   

    像IP库这种“频繁查询但修改很小”的数据,就应该这么做不要说什么优化数据库,数据库也会把部分内容缓存到数据库;数据库为什么会有算法去管理哪些缓存哪些不缓存,是因为内存对于整个数据库的数据来说少的可怜;如果内存够大,数据库也会把这些数据都缓存到内存中;因为它们是“刚才被查询的”;你唯一要考虑的就是你需要缓存的所有数据所占的内存是不是大的不能承受,仅此而已;这根本不造成web服务器的压力;放到applecation域,整个应用只需要有一套这个list即可;
      

  16.   

    仅供参考1、分表,就是把
        1.xxx.xxx.xxx 放到 IPMap_001 表中
        2.xxx.xxx.xxx 放到 IPMap_002 表
        3.xxx.xxx.xxx 放到 IPMap_003 表
        ......
        254.xxx.xxx.xxx 放到 IPMap_254 表
    这样每个表中存放的数据量会少很多,查询速度比放到一个表中要快2、参考操作系统虚拟内存的交换算法,即创建一个固定长度的列表,当客户进行查询时,先到内存列表中找,如果找到则返回内存中的数据,如果没有找到,则到数据库中查询数据返回给客户,同时把查到的数据存添加到列表中,如果列表已满,则从列表中将最长时间没有被访问过的数据淘汰出列表。3、添加一块固态硬盘,专用存放对访问速度要求高,并且读取数据频繁的数据
      

  17.   

    另外摒弃一些不需要的字段,只保留需要的字段,看看能不能减少内存使用量。
    还有,Eclipse不能运行那个程序,可能是设置得不正确,而不是内存不足的问题。
      

  18.   

    对的,要在eclipse配置JRE的地方配置运行时JVM的内存。那么配置文件里面的配置是起什么作用的呢?
      

  19.   

    在eclipse里设置jvm虚拟机支持的最内存大值。
      

  20.   

    不能一次性读取,最好使用分页
    在SQL语句上加个从某个范围到某个范围
    Mysql  是limit  ,Oracle 是 rowcount,具体可以自己查查
      

  21.   

    设置vm argument也不是解决问题的根本方法,要是千万条数据呢,物理内存是固定的