Java内存泄露问题的分析

发表于:2010-1-06 10:25

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:51Testing软件测试网采编

  3.尽量避免型

  class A{
  B b=new B(this);
  }
  class B{
  A a;
  B(A a){this.a=a;}
  }

  这个存在互相引用,可能导致孤岛现象,但是这个不会造成内存泄露不过我自己觉得这个会降低GC的效率,就从我的智力来看,我觉得这种情况比一般情况难以判定怎么回收!当然GC比我聪明,不过应该也要动一点脑子吧。

  在把组件提交到集成阶段之前,每个开发人员必须对他们的组件进行性能单元测试。传统的单元测试仅仅重视功能而忽略性能。

  在单元测试期间,性能单元测试意味着需要用以下的工具分析组件:

  • Memory profiler
  • Code profiler
  • Coverage profiler

  Memory profiler 在用例开始前和在用例结束后运行垃圾回收并且记录堆的快照。从这些数据中,我们能看到用例的内存影响及该用例在内存中留下的具体对象列表。开发人员需要检查那些对象以确认在用例执行完成后那些对象就应该保留在内存中。当用例完成后,如果对象被疏忽而留在堆中,那么这就是Java内存泄漏,并且我们这些称为游离对象,有时也可称为遗留对象引用。

  下一个需要寻找的内存问题称为对象循环。在用例执行期间,所记录的细粒度的堆的采样信息,结合创建和删除的数量,说明了对象被创建和删除的次数。如果对象被迅速地创建并删除,那么它将给JVM带来非常大的压力。每个被创建及删除的对象仅能由垃圾搜集回收,并且对象循环显着地增加垃圾回收的频率。这种情况通常发生在一个循环或嵌套循环内部的对象创建的情况。

  让我们看看以下的代码:

  for( int i=0; i<object.size(); i++ ) {
  for( int j=0; j<object2.size(); j++ ) {
  int threshold = system.getThreshold();
  if( object[i].getThing() - object2[j].getOtherThing() > threshold ) {
  // Do something
  }
  }
  }

  在这个例子中,外部循环遍历object中的所有项目,并且每个项目都遍历object2的所有项目。如果object包含1000个项目并且 object2也包含了1000个项目,那么被定义在循环内部的代码将被执行1000 *1000次,或1百万次。在这种代码下,阈限变量将每次在内部循环运行时(当该对象的引用超出作用域范围时对象将被销毁)被分配和销毁。如果你在Memory profiler里看到这个代码,你将看到一百万个阈限实例被创建并被销毁。

  代码应该用如下的方式重写来消除这种情况:

  int threshold = system.getThreshold();
  int threshold = system.getThreshold();
  for( int j=0; j<object2.size(); j++ ) {
  if( object[i].getThing() - object2[j].getOtherThing() > threshold ) {
  // Do something
  }
  }
  }

  现在,对与一百万次循环,阈限变量只分配一次。阈限变量的影响从至关重要变为微不足道。

  在基于Web应用中,我们经常看到的关于对象循环的场景是在在请求的上下文中创建对象。在单次使用情况下,这并不是问题,不过一但当用户的负载显着增加时,这个问题就很快变得很明显。你必须做出的决定是,这个对象是否需要基于每个请求创建,或者如果一旦它被创建,那么可被缓冲以被随后的请求重用。如果对这个问题的回答是后者,那么你可以消除该对象的循环使用问题。图1显示当对象循环发生时堆的视图。

  eclipse 有启动参数里设置jvm大小,因为eclipse运行时自己也需要jvm,所以eclipse.ini里设置的jvm大小不是具体某个程序运行时所用jvm的大小,这和具体程序运行的jvm大小无关。

  那么怎么才能设置某个程序的jvm大小呢(当然控制台运行的话不会存在这个问题,如:java -Xms256m -Xmx1024m classname,这样就可以把当前程序的jvm大小给设定)?

  因为eclipse里默认的一个程序的jvm配置为:-Xms8m -Xmx128m,所以我们的处理耗内存比较大时需要手动调整一下,以便不会内存溢出。具体的设置方法为:

  选中被运行的类,点击菜单‘Run->Run Configurations...’,选择(x)=Argument标签页下的vm arguments框里输入 -Xmx512m, 保存运行就ok了。

  我经常处理大的浮点矩阵,所以我用的是 -Xmx1024m

33/3<123
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号