首页>新闻>沈阳java开发选达内

沈阳java开发选达内

来源:达内教育IT培训沈阳分校

时间:2021/7/31 16:16:51

沈阳java开发选达内,小编在这里为您推荐达内教育,凭借雄厚的技术研发实力、过硬的教学质量、成熟的就业服务团队,为学员提供强大的职业竞争力,在用人企业中树立了良好的口碑.为不影响您的学习,来校区前请先电话或QQ咨询,方便我校安排相关课程的专业老师为您解答~接下来达内教育的小编为您分享,Java中八个潜在的内存泄露风险,你知道几个?

4. 非静态内部类

  要知道,所有的非静态类别类都持有外部类的引用,因此某些情况如果引用内部类可能延长外部类的生命周期,甚至持续到进程结束都不能回收外部类的空间,这类内存溢出一般在Android程序中比较多,只要MyAsyncTask处于运行状态MainActivity的内存就释放不了,很多时候安卓开发者这样做只是为了在内部类中拿到外部类的属性,殊不知,此时内存已经泄露了。

  public class MainActivity extends Activity {

      @Override

      protected void onCreate(Bundle savedInstanceState) {

          super.onCreate(savedInstanceState);

          setContentView(R.layout.main);

          new MyAsyncTask().execute();

      }

      private class MyAsyncTask extends AsyncTask {

          @Override

          protected Object doInBackground(Object[] params) {

              return doSomeStuff();

          }

          private Object doSomeStuff() {

              //do something to get result

              return new MyObject();

          }

      }

  }

  5. 重写了finalize()的类

  如果运行下面的这个例子,则较终程序会因为OOM的原因崩溃。

  public class Finalizer {

      @Override

      protected void finalize() throws Throwable {

      while (true) {

             Thread.yield();

        }

    }

  public static void main(String str[]) {

    while (true) {

          for (int i = 0; i < 100000; i++) {

              Finalizer force = new Finalizer();

          }

     }

   }

  }

  JVM对重写了finalize()的类的处理稍微不同,首先会针对这个类创建一个java.lang.ref.Finalizer类,并让java.lang.ref.Finalizer持有这个类的引用,在上文中的例子中,因为Finalizer类的引用被java.lang.ref.Finalizer持有,所以他的实例并不能被Young GC清理,反而会转入到老年代。在老年代中,JVM GC的时候会发现Finalizer类只被java.lang.ref.Finalizer引用,因此将其标记为可GC状态,并放入到java.lang.ref.Finalizer.ReferenceQueue这个队列中。等到所有的Finalizer类都加到队列之后,JVM会起一个后台线程去清理java.lang.ref.Finalizer.ReferenceQueue中的对象,之后这个后台线程就专门负责清理java.lang.ref.Finalizer.ReferenceQueue中的对象了。这个设计看起来是没什么问题的,但其实有个坑,那就是负责清理java.lang.ref.Finalizer.ReferenceQueue的后台线程级是比较低的,并且系统没有提供可以调节这个线程级的接口或者配置。因此当我们在使用使用重写finalize()方法的对象时,千万不要瞬间产生大量的对象,要时刻谨记,JVM对此类对象的处理有特殊逻辑。

  6. 针对长字符串调用String.intern()

  如果提前在

  src/test/resources/large.txt中写入大量字符串,并且在Java 1.6及以下的版本运行下面程序,也将得到一个OOM。

  @Test

  public void givenLengthString_whenIntern_thenOutOfMemory()

    throws IOException, InterruptedException {

      String str

        = new Scanner(new File("src/test/resources/large.txt"), "UTF-8")

        .useDelimiter("\\A").next();

      str.intern();

      

      System.gc();

      Thread.sleep(15000);

  }

  原因是在Java 1.6及以下,字符串常量池是处于JVM的PermGen区的,并且在程序运行期间不会GC,因此产生了OOM。在Java 1.7以及之后字符串常量池转移到了HeapSpace此类问题也就无需再关注了。

  • 上一篇:沈阳大数据培训
  • 下一篇:沈阳靠前的java学习班
  • 相关推荐 更多>

    沈阳当地有名的短视频拍摄剪辑培训...

    沈阳学视频剪辑有什么靠谱的培训机...

    沈阳皇姑区短视频剪辑培训去哪里

    沈阳评价高的pr影视后期剪辑培训...

    沈阳精选几家口碑出名的短视频拍摄...

    沈阳本地值得力推的短视频拍摄剪辑...

    预约体验课

    版权所有:搜学搜课(www.soxsok.com)

  • 在线咨询
  • 电话咨询
  • 预约试听

  • ;