面试中经常会被面试官问到关于 JVM 的知识, 由于一直在大学的象牙塔中, 也没有好好了解过其中的奥秘.
觉得这一块也挺重要的, 所以专门找了一些资料, 学习了一下.
1. 什么是垃圾回收机制
垃圾回收机制, 也叫做 GC. 这可以说是 java 最强的特性之一, GC 直击 C++ 开发痛点, 无需开发人员手动管理内存, 只需要放肆的 New 即可. Java 会自动回收过期的对象.
但是很不幸, Java 也存在内存泄漏.
2.GC 是如何判断可以回收的?
GC 有两种方式判断是否回收对象. 一种是引用计数法, 另一种是可达性分析.
1. 引用计数法
引用计数法, 就是一个对象, 被引用一次, 就 + 1, 当引用数为 0 的时候, 就说明该对象不再被引用, 不再被需要, 此时就会被 GC 回收, 但是....
当 A 引用了 B,B 又引用了 A, 两个对象互相引用, 那么这么两个对象永远不会被 GC 所回收.
2. 可达性分析
可达性分析. 从 GC ROOTS 开始向下搜索, 搜索经过的路成为引用链, 当一个对象到 GC ROOTS 无任何引用链可达时, 证明该对象是不可用的. 则判断对象可以进行回收 .
引用链可以解决循环引用的的问题.
GC ROOTS 包括以下这么对象:
虚拟机栈中引用的对象
方法区中类静态属性引用的对象
方法区中常量引用的对象
本地方法栈中 JNI[即一般说的 Native]引用的对象
3. 什么是内存泄漏
内存泄漏就是在程序运行中, 已经用不到的对象, 但是因为某种原因, 躲过了上面两种回收检测机制, GC 没有进行回收, 从而该对象一直占用在内存中.
偶尔的内存泄漏对程序不会有太大的影响, 但是积少成多, 不管多大的内存, 迟早会被这些无用的对象耗尽内存, 最终造成内存溢出
可以说这是程序编码中的漏洞, 程序的减分项.
4. 什么时候会出现内存泄漏
1. 当一个长生命周期的对象引用了一个短生命周期的对象时, 就会发生内存泄漏. 比如下面的这段代码:
- public class LongLifeCycle(){
- public Object object;
- public void AMethod(){
- object = new Object;
- }
- }
比如这种情况, 如果调用了 Amethod()方法, 就 new 了一个 object 的引用, 但是我们也许仅仅只在这个方法中需要用到这个 object 对象; 当这么方法结束时, 我们就希望 GC 会将这个 object 回收.
但是, 类中全局的 object 对象一直持有着引用, 所以 GC 并不会如我们希望的这样做. 这么一个小小的 object 也许在小体量的程序中掀不起什么大浪, 但是如果我们有百万级的用户, 并且这个类是多例的.
那么这就是一个大问题了.
解决方法也很简单. 就是将现在的全局变量写到方法中, 变成局部变量就好了. 这也算是一点点细节..
2. 集合中的内存泄漏
看了之后才发现, 我一直以来都有着这样的错误.
很多时候, 在循环添加数据时, 为了保证对象引用的不同, 有些值我们不能定义在循环的外面. 所以一旦集合对象 (比如 HashMap,ArrayList 等) 发生了泄漏, 会连带着很多对象一起泄漏.
- ArrayList<Object> list = new ArrayList<>();
- for(int i=0;i<10;i++){
- Object object = new Object();
- list.add();
- object =null;
- }
这种时候我们创建了十个 Object 对象, 每次循环中虽然释放了 object 对象. 但是 list 中依然引用着 object 对象 (虽然不是同一个 object 对象) 所以 GC 不会进行回收, 只有 objext 从 list 中移除, 或 list=null 时; 才会将这一串数据全部释放掉. 所以在创建一些数据体量比较庞大的集合时, 一定要多个心眼. 看看是否会及时释放.
4. 内存泄漏和内存溢出
内存泄漏和内存溢出, 两者的概念是完全不一样的, 但是他们有着一些关联.
内存溢出(out of memory): 当程序在申请内存时, 没有足够的内存供其使用, 就会出现 out of memory
内存泄漏(memory leak): 当一个对象不在被使用, 但是一直占据着一个内存时, 就发生了一次内存泄漏, 就像上面说的, 偶尔一次泄漏可能不是什么问题.
但是大量的泄漏就是程序弊病. 内存泄露堆积后, 无论多少内存, 迟早会被占用光, 内存泄漏是内存溢出的诱因之一
JVM 学习笔记(一): 垃圾回收机制? 原理? 内存泄漏? 内存溢出?
来源: http://www.bubuko.com/infodetail-3329841.html