文章目录
自动内存管理
java内存区域与内存溢出异常
运行时数据区域
Program Counter Register
Java Virtual Machine Stack
Native method Stack
Java 堆
Method area
直接内存
垃圾收集器和内存分配策略
那些对象需要回收?
引用计数法
可达性分析
引用分类
两次标记
回收方法区
什么时候回收?
如何回收?
heap的内存划分
1.标记-清除算法
标记:标记出所有要回收的对象
 清除:回收被标记对象
 缺点:效率低,这两个操作效率都不高
 空间问题,形成大量不连续碎片空间。当以后需要分配较大的对象时,无法找到足够大的连续空间,触发gc。
2.标记-复制算法
内存分为相等的两块,需要回收时,把存活的对象拷贝到另一半,清除当前的整个块,以保证空间连续性。
 缺点:代价高。
 现在一般分为三块,Eden和两块较小的Survivor。当回收时,将存活对象放到另一个Survivor中,清除当前Survivor和Eden.
3.标记-整理算法
标记:标记所有要回收的对象。
 整理:将存活对象向一段移动,然后直接清理到边界以外的内存空间
4.分代收集算法
分代:新生代,老生代
 新生代:存活少,使标记-复制算法。
 老生代:存活多,使用标记清除或标记整理算法。
代码如何产生不可达变量
非线程对象不被指向或超出作用域
 线程对象线程未启动或停止
改变对象引用,置为null或指向其他对象。
Object x=new Object();//object1 
Object y=new Object();//object2 
x=y;//object1 变为垃圾 
x=y=null;//object2 变为垃圾
 
超出作用域
if(i==0){ 
      Object x=new Object();//object1 
   }//括号结束后object1将无法被引用,变为垃圾 
 
类嵌套导致未完全释放
class A{ 
      A a; 
   } 
   A x= new A();//分配一个空间 
   x.a= new A();//又分配了一个空间 
   x=null;//将会产生两个垃圾 
 
线程中的垃圾
class A implements Runnable{   
     void run(){ 
       //.... 
     } 
   } 
   //main 
   A x=new A();//object1 
   x.start(); 
   x=null;//等线程执行完后object1才被认定为垃圾 
 










