内存溢出就是指对内存使用的增长速度过快,垃圾收集跟不上就会出现内存溢出,一般在内存快要溢出之前会进行一次full gc回收大量内存,如果full gc之后还是空间不够就会报oom的错误,但是full gc也不是一定会在内存泄漏之前执行,只是在要放的对象相当大的情况下,无论如何回收内存也不可能放下这个对象时就不会进行一次full gc而实直接报OOM的错误。
内存泄漏和内存溢出不一样,严格来讲,内存泄漏是指已经不被我们使用的对象还在内存当中并且不能被我们的垃圾回收算法回收,发生内存泄漏并不会立即出现错误,当内存泄漏过多时才会报OOM的错误,广义的来说,一些对象生命周期过长也可以归类于内存泄漏。
安全点就是程序可以停下来发生gc的地方,当然了,安全点的多少也不能是随意的,多了会影响性能,少了垃圾回收会受到影响。一般的安全点都是选择在执行时间长的地方,例如循环等等,
当要发生gc时程序如何中断? ---->采用主动式中断的方法,每个安全点设置有中断标准,当程序执行到一个安全点的时候就开始判断是否要中断。
俺去那区域是指一段引用关系不会发生改变的代码,当一个线程运行到安全区域中时,这个线程会标记进入安全区域,而且如果这个时候开始发生gc了,被标记进入安全区域的线程就会被jvm忽略,然后是当这个线程要离开安全区域时要进行判断,如果正在发生gc就要等待gc完成才能继续执行,没有发生gc可以直接继续执行离开安全区域。
什么是强引用? ---->强引用一般就是new的一个对象付给一个变量,或者再把这个变量赋值给另一个变量,这种能够形成强引用,强引用时不会被回收的,即使时内存不足也只会报oom而不会回收强引用,另一个是强引用时内存泄漏的主要原因(主要贡献者)
软引用详解: —>软引用时可能被回收的,软引用一般被用在高数缓存中,一般在要发生内存溢出之前会进行引用的二次回收,第二次时因为之前发生了一次gc回收后还是会发出内存溢出,这个时候就开启二次回收,这次就是主要回收软引用,如果二次软引用回收后内存足够就不会发生oom,不够还是会发生oom,如果一次gc回收后没有oom的可能发生就不会进行二次软引用的回收。
弱引用详解 ----->弱引用并不会等到内存快要溢出时才考虑回收,而是见到就回收,每次gc都会回收所有的弱引用。
虚引用 有点没有理解
一般来说,回收的垃圾就是回收内存中不可达对象, 什么是不可达对象:在内存中没有被引用的对象。 判断方法: 1:引用计数法 2:可达性分析法(Java中使用的方法)
什么是引用计数法? ----->给对象添加一个引用计数器,每当一个地方引用它时,计数器加1,每当引用失效时,计数器减少1.当计数器的数值为0时,也就是对象无法被引用时,表明对象不可在使用,这种方法实现简单,效率较高,大部分情况下不失为一个有效的方法。但是主流的Java虚拟机如HotSpot并 没有选取引用计数法 来回收内存,主要的原因难以解决对象之间的相互循环引用的问题
什么是可达性分析法 —> 根搜索算法的基本思路就是通过一系列名为”GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。
那么问题又来了,如何选取GCRoots对象呢?在Java语言中,可以作为GCRoots的对象包括下面几种: (1). 虚拟机栈(栈帧中的局部变量区,也叫做局部变量表)中引用的对象。 (2). 方法区中的类静态属性引用的对象。 (3). 方法区中常量引用的对象。 (4). 本地方法栈中JNI(Native方法)引用的对象。
以上就是判断不可达对象的办法,不可达对象在垃圾回收中将会被回收,但是也不是一定被回收(比如局部变量表的引用还没有被覆盖,栈帧又未退出时)