不诗意的女程序媛不是好厨师~ 转载请注明出处,From李诗雨— blog.csdn.net/cjm24848365…
关于回收机制我曾经写过一篇很详细的文章,感兴趣的可以去看一下https://blog.csdn.net/cjm2484836553/article/details/103842357。
但是!由于我是那种 "一看就会 ,一说就废" 型的面试者,所以面试之前 我就希望 可以整理的 尽可能浓缩浓缩再浓缩,否则道理我都懂,就是记不住呀!
来吧,直奔主题!
java回收机制 主要是通过判断 我们对象的存活情况来进行的。
我们采用的主要是 可达性分析 算法。
可达性分析 就是依据 我们的对象能不能到达GCRoots 作为标准的。
在Java中 可作为GC Roots的对象包括:
1.方法区: 类静态属性的对象;
2.方法区: 常量的对象;
3.虚拟机栈(本地变量表)中的对象.
4.本地方法栈JNI(Native方法)中的对象。
下面我们再通过代码,来理解一下可达性分析是如何计算的:
/** * 可达性分析算法 */ Object o =new Object(); static Object GCRoot1 =new Object(); //GC Roots final static Object GCRoot2 =new Object();//GC Roots public void method1() { //可达 Object object1 = GCRoot1; //=不是赋值,在对象中是引用,传递的是右边对象的地址 Object object2 = object1; Object object3 = object1; Object object4 = object3; } public void method2(){ //不可达(方法运行完后可回收) Object object5 = o;//o不是GCRoots Object object6 = object5; Object object7 = object5; } //本地变量表中引用的对象 public void stack(){ Object ostack =new Object(); //本地变量表的对象 Object object9 = ostack; //以上object9 在方法没有(运行完)出栈前都是可达的 } 复制代码
我画个图来分析吧:
这下你该明白java的回收机制了吧,哈哈哈哈哈~
最后我们再来说一下 如何减少OOM的概率 :
1.尽可能少的发生内存泄漏
因为因为一旦内存泄漏多,就会有许多不需要的内存遗留在外面,就容易造成OOM。
2.尽可能不要在 循环 申请内存
因为可达性分析的存在(虚拟机栈(本地变量表)中的对象可作为GC Roots),当方法执行过程中,对象会在GC Roots中,而不能及时被GC回收掉,从而造成内存溢出。
3.尽可能不在调用次数多的函数中申请内存
(比如说一些回调函数)
积累点滴,做好自己~