十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
1、首先得搞清楚什么叫内存泄露,简单来说就是一个东西放在内存里的时间太长了,当你的程序都跑完了,它还存在那里。这时它是白白的占用了你的内存,累积起来占用的内存越来越多……最后就会导致JVM报错:out of memory。
在南沙等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都网站制作、成都做网站、外贸营销网站建设 网站设计制作按需求定制网站,公司网站建设,企业网站建设,高端网站设计,全网营销推广,成都外贸网站制作,南沙网站建设费用合理。
2、一般情况下,别人如果能指出你的系统(程序)内存溢出,这个人应该还是挺厉害的。通常对于新人来说,喜欢把变量直接定义在class下(此时称之为实例变量,或者成员变量),那么在方法里调用后,这个实例变量是不会被释放的,大量的这样使用就可能会引发内存泄露。
3、把变量定义在方法里,当这个方法执行完毕后内存就得到释放了,这是个好习惯。
4、如果想要看到内存溢出,可以按这样的思路去尝试一下:定义一个静态的实例变量(list或其它集合),然后在一个方法里循环往这个静态变量塞东西,直到这个实例变量撑爆你的jvm内存。很快你就能看到out of memory……
import java.util.ArrayList;
import java.util.List;
public class MemoryTest {
private static List list = new ArrayList();
private static int count = 0;
public static void main(String[] args) throws InterruptedException {
System.out.println("申请前的可用内存 = "+getFreeMemory());
while(true){
list.add(new byte[1024*1024]);//用实例变量申请1M内存,当方法执行完毕时,这个static的变量是不会被释放
count++;
if (count % 100 == 0) {
System.out.println("当前list.size()="+list.size()+",可用内存 = "+getFreeMemory());
Thread.sleep(500);
}
}
}
public static long getFreeMemory() {
return Runtime.getRuntime().freeMemory() / (1024 * 1024);
}
}
java程序大家都知道,内存溢出是经常见的错误,下面从基本的开始分析!
内存溢出是由于没被引用的对象(垃圾)过多造成JVM没有及时回收,造成的内存溢出。如果出现这种现象可行代码排查:
一)是否App中的类中和引用变量过多使用了Static修饰 如public staitc Student s;在类中的属性中使用 static修饰的最好只用基本类型或字符串。如public static int i = 0; //public static String str;
二)是否App中使用了大量的递归或无限递归(递归中用到了大量的建新的对象)
三)是否App中使用了大量循环或死循环(循环中用到了大量的新建的对象)
四)检查App中是否使用了向数据库查询所有记录的方法。即一次性全部查询的方法,如果数据量超过10万多条了,就可能会造成内存溢出。所以在查询时应采用“分页查询”。
五)检查是否有数组,List,Map中存放的是对象的引用而不是对象,因为这些引用会让对应的对象不能被释放。会大量存储在内存中。
六)检查是否使用了“非字面量字符串进行+”的操作。因为String类的内容是不可变的,每次运行"+"就会产生新的对象,如果过多会造成新String对象过多,从而导致JVM没有及时回收而出现内存溢出。
如String s1 = "My name";
String s2 = "is";
String s3 = "xuwei";
String str = s1 + s2 + s3 +.........;这是会容易造成内存溢出的
但是String str = "My name" + " is " + " xuwei" + " nice " + " to " + " meet you"; //但是这种就不会造成内存溢出。因为这是”字面量字符串“,在运行"+"时就会在编译期间运行好。不会按照JVM来执行的。
在使用String,StringBuffer,StringBuilder时,如果是字面量字符串进行"+"时,应选用String性能更好;如果是String类进行"+"时,在不考虑线程安全时,应选用StringBuilder性能更好。
知道原因了,解决起来就非常简单了。
内存溢出是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能提供的最大内存。为了解决Java中内存溢出问题,我们首先必须了解Java是如何管理内存的。Java的内存管理就是对象的分配和释放问题。在Java中,内存的分配是由程序完成的,而内存的释放是由垃圾收集器(Garbage Collection,GC)完成的,程序员不需要通过调用GC函数来释放内存,因为不同的JVM实现者可能使用不同的算法管理GC,有的是内存使用到达一定程度时,GC才开始工作,也有定时执行的,有的是中断式执行GC。但GC只能回收无用并且不再被其它对象引用的那些对象所占用的空间。Java的内存垃圾回收机制是从程序的主要运行对象开始检查引用链,当遍历一遍后发现没有被引用的孤立对象就作为垃圾回收。引起内存溢出的原因有很多种,常见的有以下几种:l 内存中加载的数据量过于庞大,如一次从数据库取出过多数据;l 集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;l 代码中存在死循环或循环产生过多重复的对象实体;l 使用的第三方软件中的BUG;l 启动参数内存值设定的过小;
第一对所有的代码包括页面中的java代码都进行一遍彻底的回顾检查,
1.对那些静态(static)的对象要特别留神,特别是类型为Map,List,Set的,静态的变量会一直驻存在内存中,生命周期比较长,不会被垃圾器回收。
2.对于代码,要审查是否生成了大量的冗余的对象,还有一些逻辑业务处理的类,
算法是否过于复杂,调整算法,对于代码认真审查,再仔细重构一遍代码,能提高代码质量,提高程序运行稳定性。
3.Java中的内存溢出大都是因为栈中的变量太多了。其实内存有的是。建议不用的尽量设成null以便回收,多用局部变量,少用成员变量。
1),变量所包含的对象体积较大,占用内存较多。
2),变量所包含的对象生命周期较长。
3),变量所包含的对象数据稳定。
4),该类的对象实例有对该变量所包含的对象的共享需求。
4.在我的程序中对静态变量的优化后,使程序占用内存量至少提升了5k-10k。所以也不容忽视。
第二还有就是String类相关的东西:
1.字符串累加的时候一定要用StringBuffer的append方法,不要使用+操作符连接两个字符串。差别很大。而且在循环或某些重复执行的动作中不要去创建String对象,因为String对象是要用StringBuffer对象来处理的,一个String对象应该是产生了 3个对象(大概是这样:))。
2.字符串length()方法来取得字符串长度的时候不要把length放到循环中,可以在循环外面对其取值。(包括vector的size方法)。特别是循环次数多的时候,尽量把length放到循环外面。
int size = xmlVector.size();
for (int i = 2; i size; i++) {
。。。
}
3 写代码的时候处理内存溢出
try{
//do sth
....
}catch (outofmemoryerror e){//可以用一个共通函数来执行.
system.out.print (“no memory! ”);
system.gc();
//do sth again
....
}
4.对于频繁申请内存和释放内存的操作,还是自己控制一下比较好,但是System.gc()的方法不一定适用,最好使用finallize强制执行或者写自己的finallize方法。 Java 中并不保证每次调用该方法就一定能够启动垃圾收集,它只不过会向JVM发出这样一个申请,到底是否真正执行垃圾收集,一切都是个未知数。