解决方案 »
- android 开发wenservice问题(java.rmi.RemoteException cannot be resolved)
- java中比较运算符==疑问
- jar包用winRar解压,然后又压缩并改后缀rar为jar有什么问题吗
- JAVA与C++语言比较
- 微软的视频太牛了!
- 如何把一个二进制文件读到一个byte数组中?
- Java 如何解释STL文件 (3D立体打印用)
- 有编过SMPP短信程序的吗??
- 高分求解JMF视频播放问题!
- 关于ObjectInputStream 报错 invalid stream heade
- java poi 导出excel不能超过65536行
- Apache lucene RangeQuery jar包
linkedlist比较适合频繁增删的
1、大文件一次性读入会占用很多的内存,轻则拖慢应用,重则系统崩溃。
2、读入内存,一次性保存在一个ArrayList中会进一步增加内存空间消耗。解决方法:
大文件不要一次性读入内存,逐行处理,取一行处理一行。这样后面用到的ArrayList需要存储的值也自然少了。
为了加快处理速度,可以使用多线程等方式并发处理,对刚接触Java的人来讲还略早。
然后要边读边处理好像可以用ArrayBlockingQueue之类的,线程安全方便多线程
两种list实现的方法不一样
double orix,oriy,dirx,diry;
int hitcount,raynum;
if (scanner.hasNextDouble()){
orix=scanner.nextDouble();oriy=scanner.nextDouble();
dirx=scanner.nextDouble();diry=scanner.nextDouble();
hitcount=(int)scanner.nextDouble();
raynum=(int)scanner.nextDouble();
ray newRay=new ray(orix,oriy,dirx,diry,hitcount);
newRay.setNo(raynum);
InputRays.add(newRay);
}
else {
String temp=scanner.next();
}
}
这样写有问题,因为你将创建的对象放入list中,垃圾回收机制是不能回收被list持有的对象,如果对象太多就会内存溢出。你可以一次创建5000个对象,将这些对象存入文件或者数据库中。这样就不会内存溢出了。
用到了多线程、锁、匿名类、区块等等。本来还想用lambda表达式的,但是怕楼主jdk版本不够高……
Ray[] buffer = new Ray[100];
{
for (int i=0;i<100;i++) {
buffer[i] = new Ray();
}
}
int readPointer = 0;
int processPointer = 0;
int size = 0;
boolean eof = false;public void readRays(final String f) {
new Thread() {
public void run() {
Scanner scanner = new Scanner(new FileInputStream(f)));
while (scanner.hasNext()){
synchronized(buffer) {
if (size == 100) {
buffer.wait();
} else {
ray[readPointer].orix = scanner.nextDouble();
ray[readPointer].oriy = scanner.nextDouble();
ray[readPointer].dirx = scanner.nextDouble();
ray[readPointer].diry = scanner.nextDouble();
ray[readPointer].hitcount = (int)scanner.nextDouble();
ray[readPointer].raynum = (int)scanner.nextDouble();
size++;
readPointer = readPointer == 99 ? 0 : readPointer + 1;
if (size == 1) {
buffer.notifyAll();
}
}
}
}
eof = true;
}
}.start();
}public void processRays() {
new Thread() {
public void run() {
while (!eof){
synchronized(buffer) {
if (size == 0) {
buffer.wait();
} else {
processRay(ray[processPointer]);
size--;
processPointer = processPointer == 99 ? 0 : processPointer + 1;
if (size == 99) {
buffer.notifyAll();
}
}
}
}
}
}.start();
}
但是扩容主要影响的应该是cpu和内存读写速度,而不是内存容量。扩容后原本的数组会被垃圾回收的
爬网查了下。arraylist扩容的确要慢点,我试试改成别的看看效率。感谢提供关键词ArrayBlockingQueue,我研究一下看看。
感谢回复。这些对象后面还要用到,如果存到文件或者数据库,后面用的时候还是要加载到内存的吧。还是说也是边读边处理这样?或者你的意思是这样读取,垃圾回收机制就可以工作了?还请指导。
非常感谢,还有例程,免了我爬网找例程之苦。多线程、匿名类、锁、区块我还没接触到,先学习研究一下。感谢提供关键词及例程。
感谢回复。的确不能一次读取,后面我又试了一个GB级别的文件,直接内存不够了。
感谢回复。批量处理看上去挺不错,可能没有边读边处理和多线程并发处理优雅高效,但对我这样技术小白应该是容易上手的,可以先从这里研究看看。
解决方法就是一开始创建ArrayList时给足够的初始长度,这样后面就不用每次改变数组长度了
List list = new ArrayList(100000)
希望能帮到你