JVM垃圾收集机制探寻与代码优化

首先了解JVM内存模型

 

 创建的对象存在堆里,栈,先从main方法进入,调用run方法,逐一向上执行,run方法中的this指代car,调用fire方法

然后fire方法先结束,再run,最后到main方法终止,栈的特点:先执行的方法后终止。

JVM的作用 :

        举个反例:C语言通过malloc()和free()这两个方法来实现分配,释放内存空间,一方面,对已释放的内存,未曾分配

                          的内存做释放,否会造成死机;另一方面,对不再使用的内存不释放,会浪费系统内存,甚至内存枯竭

如:

int main(int argc,char* argv[])

{

     int  *p;//定义一个int类型的指针

     p = (int *)malloc(4);//分配4个连接的内存单元给指针p

     free(p);//释放指针p所指向的内存单元

     printf("Hello ");

     return 0;

}

而Java中就存在JVM垃圾收集机制,解决这类问题;

一、JVM如何发现垃圾:

1、引用计数法:

当一个对象被引用了一次就+1,结束引用就-1,引用为0的时候就会被当作垃圾被处理(当main方法退出后,方法里所有的引用都为0)

缺:无法判断相互引用的垃圾对象

对于引用计数法的缺陷提出了另一个方法

2、根搜索算法(GC Root):

没有根或者没有被有根对象引用的对象将会被垃圾回收。(根:如变量、常量等)

 二、回收、清理垃圾

1.标记清除算法(已淘汰):

将存活对象,可回收,未使用,用不同标记标记起来,然后一块一块的清除;

缺:留下内存碎片,影响大文件存放,使用效率低;

 之后提出了分段复制算法;

2.分段复制算法:

改进了标记清除算法,回收后将同一状态的对象复制在一起,并各分一半。

缺:太过于麻烦和死板

3.标记整理算法

改进分段复制算法,提高了效率,没有太严格一定要分为一半了。

 3.分代收集算法

把堆里区域分为好几代,刚new出的对象存在Eden中,生命周期长的对象就复制放在生存区(利用分段复制法发过去),from、to区相互复制替换,生存区被多次引用的对象又被复制到老年代(Eden被垃圾回收的机率很高,生存区频率就比Eden机率小一点,老年代频率再度降低,正因为这样的处理方式提高了程序的效率)

Minor GC :把Eden区域清理垃圾(小范围,新生代)

Major GC : 大范围的清理新生代和中年代

Full GC:完整的垃圾回收

 

三、高效代码技巧

1、尽量不要在循环中使用:异常处理机制(try-catch)、new对象;

2、把频繁使用的短命对象缓存起来;

3、尽可能使用栈变量(方法内局部变量)

4、用线程池,连接池,不要自己创建;

 

举个例:内存泄漏和内存溢出

内存泄漏:垃圾回收不掉的对象

内存溢出:内存不够,导致程序崩溃

//演示内存泄漏

public class MemoryLeak{

           static List<Student> list = new ArrayList<Student>();

           public static void main(String[] args){

                     for(int i = 0;i<1000000;i++){

                    Student stu = new Student();

                    list.add(stu);

                    //stu = null;//内存泄漏,无法回收 

                    }

                    list = null;//可被GC回收

                    while(true){

                             Thread.sleep(20000);//休眠20秒

                    }

           }

}

解决方法:

调整堆内存大小:-Xms256M –Xmx512M

调整栈内存大小:-Xss2048k

调整方法区大小:-XX:MetaspaceSize=64M                                      

-XX:MaxMetaspaceSize=128M

调整方法区大小:-XX:PermSize=64M

–XX:MaxPermSize=128M  

 Java 7及以前适用

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值