技术中心

这里象征着我们的态度和能力

>JAVA遇到大批数据处理
发布者:中国IT实验室    信息来源:中国IT实验室    发布时间:2012-01-09      浏览次数:4770
分享到:

新浪微博

腾讯微博

QQ空间

豆瓣网

QQ好友

欢迎进入Java社区论坛,与200万技术人员互动交流 >>进入

  Java heap space一直是困扰我们的一个问题。像Matlab就可以一次性读取5000*5000的数据到一个矩阵matrix中。然而Java确不行。

  我遇到实验室处理一个“合并5000左右txt文档到一个txt文件中”的问题,相同的算法用Matlab就不会出现内存不足的问题,而JAVA则会报出:java.lang.OutOfMemoryError: Java heap space.从这里可以判断的说Matlab是为处理大型数据而设计(It is conceived for),所以其执行代码时对内存启动了自动的分配与管理。因为我的5000左右txt文档大约有180M,显而易见,同时读到内存肯定会出现内存空间不足的警告,所以也不怪JAVA.当然,你可以在运行JAVA代码之前提高内存分配值,但是这实际上不能从根本上解决问题。因为哪天万一还有更大的数据遇到时,你是不是还要继续增大内存?要知道现在一般电脑的内存也就2G,就算1G的也很普遍。

  所以根本上我觉得是要改变你的算法。一个很自然的思路就是:数据大了就分配处理嘛。

  所以我最后就是利用了递归的手段,将5000左右txt文档分批调入内存进行处理,处理一部分就释放一部分资源。这样不管是5000个数据文件还是7000,9000都没问题。试验测得我的情况是如果不进行分批处理而是一次性调入内存在合并文档,那最大文件数只能是2000,就是超过2000个数据文件就会出现java.lang.OutOfMemoryError: Java heap space这样的错误。

  Matlab的缺点就是速度慢。所以处理海里数据为求速度还是可以试一下用JAVA实现的。我的实验结果表明,速度相差几十倍。

  下面将一步一步介绍对这个同一问题不同的编程版本以及其结果:

  1. 以我实验室的频谱测量仪(spectrometer)对激光所获的离散采样为背景。

  本程序是属于数据处理程序,用JAVA所实现。

  spectrometer中光栅的每次采样所获得的数据被保存在一个文本文件中, 分为2列:第一列为波长值,第二列为对应的光强值。 第1次采样文本文件被命名为“000000.txt”,第二个为“000001.txt”,依次类推。 比如若让spectrometer采样3mins,大概会出现4000次采样, 被保存的文件就为000000.txt~003999.txt

  此程序使用的是二维LinkedList类型来拉取数据。 LinkedList:就是采用链表结构保存对象。 PS:JAVA中集合类分为List,Set,和Map. List又有LinkedList和ArrayList; Set分为HashSet和TreeSet; Map分为HashMap和TreeMap. 顾名思义,Hash就是由哈希表提供支持,Tree树结构提供了排序和顺序输出的功能。

  =>下载本程序所用到的存放离散采样数据文件的文件夹view plain package com.han;

  import java.io.*;import java.util.*;

  /** * 以我实验室的频谱测量仪(spectrometer)对激光所获的离散采样为背景。

  * <p> * 本程序是属于数据处理程序,用JAVA所实现。

  * <p> * spectrometer中光栅的每次采样所获得的数据被保存在一个文本文件中,* 分为2列:第一列为波长值,第二列为对应的光强值。

  * 第1次采样文本文件被命名为“000000.txt”,第二个为“000001.txt”,依次类推。

  * 比如若让spectrometer采样3mins,大概会出现4000次采样,* 被保存的文件就为000000.txt~003999.txt * <p> * 此程序使用的是二维LinkedList类型来拉取数据。

  * LinkedList:就是采用链表结构保存对象。

  * PS:JAVA中集合类分为List,Set,和Map. * List又有LinkedList和ArrayList;* Set分为HashSet和TreeSet;* Map分为HashMap和TreeMap. * 顾名思义,Hash就是由哈希表提供支持,Tree树结构提供了排序和顺序输出的功能。

  * @author han * */ public class CombinedTextSpectres { static final int N=6;//N是保存的文件名称的长度static final int M=4520;//M是保存的文件数目@SuppressWarnings({ "unchecked", "rawtypes" })

  public static void main(String[] args) { // TODO Auto-generated method stub long startTime=System.currentTimeMillis();try { //若是当前class类文件目录则用下面的getClass()。getRessource()代码//File new_file=new File(new File(new test()。getClass()。getResource("")。toURI()),"combinedFile.txt");File new_file=new File("/home/han/Desktop","combinedFile.txt");//定义合并后的文件的保存路径FileWriter fw = new FileWriter(new_file);BufferedWriter bfw=new BufferedWriter(fw);List row=new LinkedList();int num_line = 0;for(int i=0;i<M;i++){ List column=new LinkedList();/*获得每个离散采样文件的名称*/ String filename="00"+i;//"00"是保存的文件的前缀int temLength=filename.length();for(int j=0;j<N-temLength;j++){ filename="0"+filename;} filename=filename+".txt";

  //定义存放离散采样数据文件的文件夹File file=new File("/home/han/Ubuntu One/apresmidi sans pola",filename);//File file=new File(new File(new test()。getClass()。getResource("")。toURI()),filename);FileReader fr=new FileReader(file);BufferedReader bfr=new BufferedReader(fr);

  String s=null;while((s=bfr.readLine())!=null){ s=s.replace(,, .);if(i==0){ column.add(s);}else{ String[] sArray=s.split(" ");column.add(sArray[1]);} row.add(column);num_line=column.size();bfr.close();fr.close();} System.out.println("Files are all viewed");for(int i=0;i<num_line;i++){ Iterator it=row.iterator();while(it.hasNext()){ List tempList=(List)it.next();bfw.write((String)tempList.get(i));bfw.write(" ");} /*for(int j=0;j<row.size();j++){ List tempList=(List)row.get(j);bfw.write((String)tempList.get(i));bfw.write(" ");} */ bfw.newLine();} bfw.close();fw.close();System.out.println("OK");} catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace();} long endTime=System.currentTimeMillis();System.out.println("耗费时间: "+(endTime-startTime)+" ms");}

  运行结果:Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.ArrayList.subList(ArrayList.java:915)

  at java.lang.String.split(String.java:2359)

  at java.lang.String.split(String.java:2403)

  at com.han.CombinedTextSpectres.main(CombinedTextSpectres.java:64)

  2. 若减少要合并的离散数据文件个数,上面的程序是可以成功运行的。为方便读者,还是把数据源和代码分别列出如下:

  =>下载本程序所用到的存放离散采样数据文件的文件夹view plain package com.han;

  import java.io.*;import java.util.*;

  /** * 以我实验室的频谱测量仪(spectrometer)对激光所获的离散采样为背景。

  * <p> * 本程序是属于数据处理程序,用JAVA所实现。

  * <p> * spectrometer中光栅的每次采样所获得的数据被保存在一个文本文件中,* 分为2列:第一列为波长值,第二列为对应的光强值。

  * 第1次采样文本文件被命名为“000000.txt”,第二个为“000001.txt”,依次类推。

  * 比如若让spectrometer采样3mins,大概会出现4000次采样,* 被保存的文件就为000000.txt~003999.txt * <p> * 此程序使用的是二维LinkedList类型来拉取数据。

  * LinkedList:就是采用链表结构保存对象。

  * PS:JAVA中集合类分为List,Set,和Map. * List又有LinkedList和ArrayList;* Set分为HashSet和TreeSet;* Map分为HashMap和TreeMap. * 顾名思义,Hash就是由哈希表提供支持,Tree树结构提供了排序和顺序输出的功能。

  * @author han * */ public class CombinedTextSpectres { static final int N=6;//N是保存的文件名称的长度static final int M=357;//M是保存的文件数目@SuppressWarnings({ "unchecked", "rawtypes" })

  public static void main(String[] args) { // TODO Auto-generated method stub long startTime=System.currentTimeMillis();try { //若是当前class类文件目录则用下面的getClass()。getRessource()代码//File new_file=new File(new File(new test()。getClass()。getResource("")。toURI()),"combinedFile.txt");File new_file=new File("/home/han/Desktop","combinedFile.txt");//定义合并后的文件的保存路径FileWriter fw = new FileWriter(new_file);BufferedWriter bfw=new BufferedWriter(fw);List row=new LinkedList();int num_line = 0;for(int i=0;i<M;i++){ List column=new LinkedList();/*获得每个离散采样文件的名称*/ String filename="00"+i;//"00"是保存的文件的前缀int temLength=filename.length();for(int j=0;j<N-temLength;j++){ filename="0"+filename;} filename=filename+".txt";

  //定义存放离散采样数据文件的文件夹File file=new File("/home/han/Ubuntu One/spectre sans pola",filename);//File file=new File(new File(new test()。getClass()。getResource("")。toURI()),filename);FileReader fr=new FileReader(file);BufferedReader bfr=new BufferedReader(fr);

  String s=null;while((s=bfr.readLine())!=null){ s=s.replace(,, .);if(i==0){ column.add(s);}else{ String[] sArray=s.split(" ");column.add(sArray[1]);} row.add(column);num_line=column.size();bfr.close();fr.close();} System.out.println("Files are all viewed");for(int i=0;i<num_line;i++){ Iterator it=row.iterator();while(it.hasNext()){ List tempList=(List)it.next();bfw.write((String)tempList.get(i));bfw.write(" ");} /*for(int j=0;j<row.size();j++){ List tempList=(List)row.get(j);bfw.write((String)tempList.get(i));bfw.write(" ");} */ bfw.newLine();} bfw.close();fw.close();System.out.println("OK");} catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace();} long endTime=System.currentTimeMillis();System.out.println("耗费时间: "+(endTime-startTime)+" ms");}

  运行结果:Files are all viewed OK耗费时间: 14880 ms附: 运行结果即合并后的单个文件

  3. 下面的方法一样的使用二维LinkedList类型来读取数据。 但是在重新写入到单个合并文件时使用了StringBuilder, 经测试,效率和CombinedTextSpectres(第一版)差不多。

  但是依然对于大数据如超过2000个文件要合并时则出现内存泄漏。

  =>下载本程序所用到的存放离散采样数据文件的文件夹

  view plain package com.han;

  import java.io.*;import java.util.*;

  /** * 此方法一样的使用二维LinkedList类型来读取数据。

  * 但是在重新写入到单个合并文件时使用了StringBuilder,* 经测试,效率和CombinedTextSpectres(第一版)差不多。

  * <p> * 但是依然对于大数据如超过2000个文件要合并时则出现内存泄漏。

  * @author han * */ public class CombinedTextSpectres_2 { static final int N=6;//N是保存的文件名称的长度static final int M=357;//M是保存的文件数目@SuppressWarnings({ "unchecked", "rawtypes" })

  public static void main(String[] args) { // TODO Auto-generated method stub long startTime=System.currentTimeMillis();try { //若是当前class类文件目录则用下面的getClass()。getRessource()代码//File new_file=new File(new File(new test()。getClass()。getResource("")。toURI()),"combinedFile.txt");File new_file=new File("/home/han/Desktop","combinedFile.txt");FileWriter fw = new FileWriter(new_file);BufferedWriter bfw=new BufferedWriter(fw);List row=new LinkedList();int num_line = 0;for(int i=0;i<M;i++){ List column=new LinkedList();/*获得每个离散采样文件的名称*/ String filename="00"+i;//"00"是保存的文件的前缀int temLength=filename.length();for(int j=0;j<N-temLength;j++){ filename="0"+filename;} filename=filename+".txt";//定义存放离散采样数据文件的文件夹File file=new File("/media/96D0265ED0264539/Users/HAN/Documents/Thèse ISMO/DonneesLabo/10_10-14_10/spectre sans pola",filename);//File file=new File(new File(new test()。getClass()。getResource("")。toURI()),filename);FileReader fr=new FileReader(file);BufferedReader bfr=new BufferedReader(fr);

  String s=null;while((s=bfr.readLine())!=null){ s=s.replace(,, .);if(i==0){ column.add(s);}else{ String[] sArray=s.split(" ");column.add(sArray[1]);} row.add(column);num_line=column.size();bfr.close();fr.close();} System.out.println("Files are all viewed");StringBuilder sb=new StringBuilder("");for(int i=0;i<num_line;i++){ Iterator it=row.iterator();while(it.hasNext()){ List tempList=(List)it.next();sb.append((String)tempList.get(i));sb.append(" ");} //以下这种应用。size()的遍历方法在大循环的

[1] [2] [3] 下一页

4000-880-989
(24小时热线)
联系客服
微信公众号

官方公众号

小程序

©2008-2022 CORPORATION ALL Rights Reserved. 版权所有 滇ICP备09003328号-1 滇公网安备 53011102000818号
昆明那家网络公司好,新媒体运营,网站优化,网络推广,网站建设,网页设计,网站设计,网站推广,云南网站公司,昆明新媒体公司,云南网红主播,昆明SEO公司,昆明网站建设,昆明网络推广,昆明网站优化,昆明网站推广,红河网站建设,大理网络公司,曲靖网络公司,丽江网站设计,昭通网络公司,保山大数据服务,智慧高速建设,智慧校园服务,云南IDC服务商,网络安全测评,等保测评,网站关键词排名优化服务,服务客户尽超2000余家,一切尽在奥远科技,服务电话:13888956730
Baidu
map