欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

java基础-------java的内存泄漏,

来源: javaer 分享于  点击 17676 次 点评:238

java基础-------java的内存泄漏,


内存泄漏:程序运行过程中会不断的分配内存空间,那些不再使用的内存空间应该即时回收它们,从而保证系统可以再次使用这些内存,如果存在无用的内存没有被回收回来,那就是内存泄漏。

一.堆内存的分代管理1.Young代     对Young代采用复制算法只需要遍历那些处于可达状态(不知道可达状态的可以看java基础-------java的内存回收(java引用的种类)这篇博客)的对象,而且这些对象的数量较少,可复制成本不大。     Young代由一个Eden区和2个Survivor区构成,绝大多数对象先分配到Eden区中(有一些大的对象可能会直接被分配到Old代中),Survivor区中的对象都至少在Young代中经历过一次垃圾回收,这些对象在被转移到Old代之前会先保留在Survivor空间中。同一时间2个Survivor空间中有一个用来保存对象,而另一个是空的,用来在下次垃圾回收时保存Young代中的对象。每次复制就是将Eden和第一个Survivor的科大对象复制到第2个Survivor区,然后清空Eden与第一个Survivor区。

补充:复制算法就是将堆内分成两个相同的空间,从根开始访问每一个关联的可达对象,将空间A的可达对象全部复制到空间B,然后一次性回收整个空间A。

2.Old代  Old代的垃圾回收具有的特征:第一:垃圾回收的执行频率无需太高,因为很少有对象会死掉                                                   第二:每次对Old代执行垃圾回收需要更长的时间来完成基于以上考虑,垃圾回收器通常会使用标记压缩算法。这种算法可以避免复制Old代的大量对象,而且由于Old代的对象不会很快死亡,回收过程不会大量的产生内存碎片。  

补充:标记压缩算法就是垃圾回收器从根开始访问所有可达对象,将它们标记为可达状态,接下来垃圾回收器会将这些活动对象搬迁在一起。

3.Permanent代   Permanent代主要用于装载class,方法等信息,默认为64M,垃圾回收机制通常不会回收Permanent代中的对象。   次要回收:当Young代的内存将要用完的时候,垃圾回收机制会对Young代进行垃圾回收,垃圾回收机制会采用较高                      的频率对Young代进行扫描和回收。因为这种回收的系统开销比较小,因此称为次要回收。   主要回收:当Old代的内存将要用完时,垃圾回收机制会进行会进行全回收,也就是对Young代和Old代都要进行回                       收,此时回收成本就大的多了,因此称为主要回收。

注:通常,Young代的内存会先被回收,而且会使用专门的回收算法(复制算法)来回收Young代的内存;对于Old代的回收频率则要低得多。因此也会采用专门的回收算法。如果需要进行内存压缩,每个代都独立的进行压缩。

二.内存管理的技巧   1.尽量使用直接量        不应该采用new的方式创建对象,而应采用直接量创建。例如:String str=“hello”;,它会创建一个“hello”字符串, 而且JVM的字符串缓存池还会缓存这个字符串。而String str=new String ("hello"),同样创建了一个缓存在字符创  缓存池中,除此之外,str所引用的String 对象底层还包含一个char[ ] 数组,这个char[ ] 数组里依次存放了 h,e,l,l,o等字符。  2.使用StringBuffer 和StringBuilder进行字符串连接       如果程序使用多个String对象进行字符串连接运算,在运行时将生成大量临时字符串,这些字符串会保存在内存 中从而导致程序性能下降。  3.尽早释放无用对象的引用

      


 4.尽量少用静态变量    若被static 修饰的变量为类变量,因此它的生命周期与类同步,都存在Permanent代里,不会被回收 5.避免在经常调用的方法,循环中创建对象     因为在不断的循环时,要不断地为new的对象创建空间,而且这些对象的生存时间并不长,接下来系统又要回收它们所占的内存空间,在这种不断分配,回收操作中,程序的性能收到巨大的影响。 6.缓存经常使用的对象    典型的缓存是数据连接池,数据连接池里缓存了大量数据库连接,每次程序需要访问数据库是都可直接取出数据库  连接。7.尽量不要使用finalize方法   在垃圾回收器本身已经严重制约应用程序性能的情况下,如果再选择使用finalize()方法进行资源清理,这将导致垃圾回收器的负担更大,导致程序运行效率更差。8.考虑使用SoftReference(软引用)  当程序需要创建长度很大的数组时,可考虑使用SoftReference来包装数组元素,而不是直接将数组元素来引用对象   注:当系统内存紧张时,SoftReference所引用的java对象将被释放。由于通过SoftReference获取的对象可能为null,因此应用程序取出SoftReference所引用的java对象之后,应显示判断该对象是否为null,当对象为null时,因重建该对象。      

相关文章

    暂无相关文章
相关栏目:

用户点评