转载地址:http://www.cnblogs.com/hnrainll/archive/2013/11/06/3410042.html
博文简单易懂,深入浅出
自己的总结:
Part1:Java内存机制
1.堆内存空间必须使用new关键字才能开辟;
2.一个栈内存只能指向一个堆内存空间,如果要想再指向其他的堆内存空间,则必须先断开已有的指向才能分配新的指向;
3.Java本身提供垃圾收集机制(Garbage Collection,GC),会不定期回收不用的(数组和对象在没有引用变量指向它的时候,才变为垃圾)内存空间。
如下例:由于没有引用变量再去指向per2,所以per2的堆内存空间就是不再被需要的,可以被GC回收。
eg:Person per1=new Person();
Person per2=new Person();
per1.name="张三";
per1.age=30;
per2.name="李四";
per2.age=33;
per2=per1;
Part2:Java的GC回收机制
GC机制的基本算法是:分代收集,这个不用赘述。下面阐述每个分代的收集方法。
年轻代:
在新生代中,使用“停止-复制”算法进行清理,将新生代内存分为2部分,1部分 Eden区较大,1部分Survivor比较小,并被划分为两个等量的部分。每次进行清理时,将Eden区和一个Survivor中仍然存活的对象拷贝到 另一个Survivor中,然后清理掉Eden和刚才的Survivor。
这里也可以发现,停止复制算法中,用来复制的两部分并不总是相等的(传统的停止复制算法两部分内存相等,但新生代中使用1个大的Eden区和2个小的Survivor区来避免这个问题)
由于绝大部分的对象都是短命的,甚至存活不到Survivor中,所以,Eden区与Survivor的比例较大,HotSpot默认是 8:1,即分别占新生代的80%,10%,10%。如果一次回收中,Survivor+Eden中存活下来的内存超过了10%,则需要将一部分对象分配到 老年代。
用程序控制内存分配:用-XX:SurvivorRatio参数来配置Eden区域Survivor区的容量比值,默认是8,代表Eden:Survivor1:Survivor2=8:1:1.
老年代:
程序开发语句: 设 置了-XX:+HandlePromotionFailure(允许担保失败),如果允许,则只会进行MinorGC,此时可以容忍内存分配失败;如果不 允许,则仍然进行Full GC(这代表着如果设置-XX:+Handle PromotionFailure,则触发MinorGC就会同时触发Full GC,哪怕老年代还有很多内存,所以,最好不要这样做)。
方法区(永久代):
永久代的回收有两种:常量池中的常量,无用的类信息,常量的回收很简单,没有引用了就可以被回收。对于无用的类进行回收,必须保证3点:
- 类的所有实例都已经被回收
- 加载类的ClassLoader已经被回收
- 类对象的Class对象没有被引用(即没有通过反射引用该类的地方)
程序开发语句:HotSpot提供-Xnoclassgc进行控制
更多配置和控制Java的GC回收的程序语句,参考链接:http://iamzhongyong.iteye.com/blog/1333100