Ⅰ java有内存溢出吗如果有是什么情况
内存溢出是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能提供的最大内存。
所以我们应该明确:存在内存溢出的因不一定导致内存溢出的果。。。
1。JAVA操作文本文件为什么超过3万行就内存益处啊?
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(fileName)));
//PrintWriter out = new PrintWriter(fileName);
//FileOutputStream out = new FileOutputStream(fileName);
while (rs.next()) {
for (int j = 1; j <= totalColumn; j++) {
out.write(rs.getObject(j).toString());
out.write("\t");
}
out.write("\n");
out.flush();
}
}
我在代码中 写了 out.flush()用来刷新该流的缓冲; 可是当我的记录数超过3W时就报了内存益处的问题了,难道JAVA不能边读边写吗?还是out这个对象随着指向的fileName文件的边大占用内存也大了吗??到底怎么来实现用JAVA写更多的数据而不内存益处呢
答案是:就在while(rs.next()) 当rs.next()时内存不断增大,而不是写流的问题,JAVA的ResultSet真是麻烦,而且ResultSet还不能clone(); 所以记得在做项目的时候,经常要设置:jdbc.setMaxRows(100*10000); //设置能容纳100万行记录-----这个就是防止内存泄露的哈------------------- 内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
jdbc.setQueryTimeout(60*30); //设置超时时间是30分钟
2。java中的内存泄露的情况:长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是java中内存泄露的发生场景,通俗地说,就是程序员可能创建了一个对象,以后一直不再使用这个对象,这个对象却一直被引用,即这个对象无用但是却无法被垃圾回收器回收的,这就是java中可能出现内存泄露的情况,例如,缓存系统,我们加载了一个对象放在缓存中(例如放在一个全局map对象中),然后一直不再使用它,这个对象一直被缓存引用,但却不再被使用。
public class Stack { //长生命周期
private Object[] elements=new Object[10]; //当数组容器中没有东西时是无用的,但是无法回收~~elements是短生命周期
private int size = 0;
public void push(Object e){
ensureCapacity();
elements[size++] = e;
}
public Object pop(){
if( size == 0)
throw new EmptyStackException();
//这里还是引用了,只是指针变位置变化而已,他确实返回了那个对象,但是他却没有断开那个对象的引用,也就是说有两个地方会持有这个对象的引用,调用pop的地方,和elements中
return elements[--size];
}
private void ensureCapacity(){
if(elements.length == size){
Object[] oldElements = elements;
elements = new Object[2 * elements.length+1];
System.array(oldElements,0, elements, 0, size);
}
}
}
上面的原理应该很简单,假如堆栈加了10个元素,然后全部弹出来,虽然堆栈是空的,没有我们要的东西,但是这是个对象是无法回收的,这个才符合了内存泄露的两个条件(必要条件):无用,无法回收。
例子1
public class Bad{
public static Stack s=Stack();
static{
s.push(new Object());
s.pop(); //这里有一个对象发生内存泄露
s.push(new Object()); //上面的对象可以被回收了,等于是自愈了,因为引用被覆盖了
}
}
因为是static,就一直存在到程序退出,但是我们也可以看到它有自愈功能,就是说如果你的Stack最多有100个对象,那么最多也就只有100个对象无法被回收其实这个应该很容易理解,Stack内部持有100个引用,最坏的情况就是他们都是无用的,因为我们一旦放新的进取,以前的引用自然消失!
内存泄露的另外一种情况:当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet集合中单独删除当前对象,造成内存泄露。
这是属于: 集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
3。代码中存在死循环或循环产生过多重复的对象实体;
4。启动参数内存值设定的过小;
Ⅱ java 内存泄露和溢出的区别
区别在与:
内存溢出类似数组越届,超出你能存储的数据的上限
内存泄漏,就是内存使用完毕后,不能释放回收重新使用
Ⅲ java内存溢出与内存泄漏怎么解决
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of
memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。
内存泄露 memory
leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
memory leak会最终会导致out of memory!
内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。
内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。一个盘子用尽各种方法只能装4个果子,你装了5个,结果掉倒地上不能吃了。这就是溢出!比方说栈,栈满时再做进栈必定产生空间溢出,叫上溢,栈空时再做退栈也产生空间溢出,称为下溢。就是分配的内存不足以放下数据项序列,称为内存溢出.
Ⅳ java中内存溢出和内存泄漏的区别
我的理解是这样的,可能不对,没有关注过:
溢出:是在代码使用过量的占用内存,导致系统分配的内存不够用。
泄露:不合理的代码使用,导致部分已经无效的内存不能释放,随着运行时长,占用越来越高
Ⅳ 什么原因可导致java内存泄漏
Java内存泄露
一般来说内存泄漏有两种情况。一种情况如在C/C++语言中的,在堆中的分配的内存,在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉(如指针重新赋值);另一种情况则是在内存对象明明已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)。第一种情况,在Java中已经由于垃圾回收机制的引入,得到了很好的解决。所以,Java中的内存泄漏,主要指的是第二种情况。
可能光说概念太抽象了,大家可以看一下这样的例子:
1 Vector v=new Vector(10);
2 for (int i=1;i<100; i++){
3 Object o=new Object();
4 v.add(o);
5 o=null;
6 }
在这个例子中,代码栈中存在Vector对象的引用v和Object对象的引用o。在For循环中,我们不断的生成新的对象,然后将其添加到Vector对象中,之后将o引用置空。问题是当o引用被置空后,如果发生GC,我们创建的Object对象是否能够被GC回收呢?答案是否定的。因为,GC在跟踪代码栈中的引用时,会发现v引用,而继续往下跟踪,就会发现v引用指向的内存空间中又存在指向Object对象的引用。也就是说尽管o引用已经被置空,但是Object对象仍然存在其他的引用,是可以被访问到的,所以GC无法将其释放掉。如果在此循环之后,Object对象对程序已经没有任何作用,那么我们就认为此Java程序发生了内存泄漏。
尽管对于C/C++中的内存泄露情况来说,Java内存泄露导致的破坏性小,除了少数情况会出现程序崩溃的情况外,大多数情况下程序仍然能正常运行。但是,在移动设备对于内存和CPU都有较严格的限制的情况下,Java的内存溢出会导致程序效率低下、占用大量不需要的内存等问题。这将导致整个机器性能变差,严重的也会引起抛出OutOfMemoryError,导致程序崩溃。
一般情况下内存泄漏的避免
在不涉及复杂数据结构的一般情况下,Java的内存泄露表现为一个内存对象的生命周期超出了程序需要它的时间长度。我们有时也将其称为“对象游离”。
例如:
1 public class FileSearch{
2
3 private byte[] content;
4 private File mFile;
5
6 public FileSearch(File file){
7 mFile = file;
8 }
9
10 public boolean hasString(String str){
11 int size = getFileSize(mFile);
12 content = new byte[size];
13 loadFile(mFile, content);
14
15 String s = new String(content);
16 return s.contains(str);
17 }
18 }
在这段代码中,FileSearch类中有一个函数hasString,用来判断文档中是否含有指定的字符串。流程是先将mFile加载到内存中,然后进行判断。但是,这里的问题是,将content声明为了实例变量,而不是本地变量。于是,在此函数返回之后,内存中仍然存在整个文件的数据。而很明显,这些数据我们后续是不再需要的,这就造成了内存的无故浪费。
要避免这种情况下的内存泄露,要求我们以C/C++的内存管理思维来管理自己分配的内存。第一,是在声明对象引用之前,明确内存对象的有效作用域。在一个函数内有效的内存对象,应该声明为local变量,与类实例生命周期相同的要声明为实例变量……以此类推。第二,在内存对象不再需要时,记得手动将其引用置空。
复杂数据结构中的内存泄露问题
在实际的项目中,我们经常用到一些较为复杂的数据结构用于缓存程序运行过程中需要的数据信息。有时,由于数据结构过于复杂,或者我们存在一些特殊的需求(例如,在内存允许的情况下,尽可能多的缓存信息来提高程序的运行速度等情况),我们很难对数据结构中数据的生命周期作出明确的界定。这个时候,我们可以使用Java中一种特殊的机制来达到防止内存泄露的目的。
之前我们介绍过,Java的GC机制是建立在跟踪内存的引用机制上的。而在此之前,我们所使用的引用都只是定义一个“Object o;”这样形式的。事实上,这只是Java引用机制中的一种默认情况,除此之外,还有其他的一些引用方式。通过使用这些特殊的引用机制,配合GC机制,就可以达到一些我们需要的效果。
Ⅵ java内存泄露和内存溢出的区别
我觉得一般情况下的话,他们两者之间的区别的话,就是他们之间的性价比是不一样的