Offer

Java垃圾回收详解

Java垃圾回收详解

  GC(Garbage Collection)的历史比java还要久远,1960年诞生的Lisp语言当时就在考虑三个问题:

  1. 哪些内存需要回收
  2. 什么时候回收
  3. 如何回收
    下面就分别回答这三个疑问,这也是Java面试中常考的知识点

JVM简介

 先简单看一下JVM运行时候的内存分布,看起来很复杂,但是一般就简单记成堆(分成新生代和老生代,新生代又分成eden和survivor,后续会讲到)、栈、方法区(当然还有其它,只是为了方便记忆)可以通过一行代码体现出来

        Object object = new Object();

 在这里,Object object是在栈中, new Object()在堆中申请,而一些类型信息会存储到方法区中。这也对于了下面这个图:
JVM

GC三个问题

 介绍完上面的基本名词,下面就可以回答GC的三个问题了。

  1. 哪些内存需要回收
     在GC工作流程中,为防止内存的浪费,GC有两种策略来回收内存
    • PC:程序计数器
       引用了对象+1,引用失效-1,虽然简单高效,但是因为不能解决大部分对象之间循环引用的问题,所以大部分JVM没有采用这种方法。
    • 可达性分析算法
       简单来说,就是自顶向下不断搜索引用,判断对象是否需要回收,具体有:堆,栈,方法区这些。
  2. 什么时候回收
     大多数情况下,在eden空间不足的情况下,就会触发(eden在上面有),jdk1.6之前策略都不同,这里我们不考虑老版本了。
  3. 如何回收
     新生代和老生代都在堆中。
    -新生代GC:大部分java对象创建回收更新快
    -老生代GC:长期存在的对象,会进入老生代,所以一般避免大对象(长字符,长数组等。)

内存泄漏和内存溢出

 一般在Java内存分配中也有两种情况,叫内存泄漏和内存溢出

  1. 内存泄漏:是指为一个对象分配内存之后,在对象已经不在使用时未及时的释放,导致一直占据内存单元,使实际可用内存减少,就好像内存泄漏了一样
  2. 内存溢出:通俗的说就是内存不够用了,比如在一个无限循环中不断创建一个大的对象,很快就会引发内存溢出

小结

 主要介绍了GC中的流程和面试常见的三个问题,基本上内存分配和各类名词都介绍到了,具体详细流程可能更复杂,这里不做深入探讨。

Empirefree

posted @ 2020-07-11 10:24  Empirefree  阅读(207)  评论(0编辑  收藏  举报