Runtime类的使用

↘锁芯ラ 提交于 2020-01-24 20:03:44

1.Runtime类的主要作用

在每一个JVM进程里面都会存在有一个Runtime类的对象,这个类的主要功能是取得一些与运行时有关的环境属性,或者创建新的进程。
在Runtime类定义的时候,它的构造方法已经被私有化了(单例设计模式的应用),以此保证,在整个运行过程中,只有唯一一个Runtime类的对象。所以在Runtime类里面提供有一个static方法,取得Runtime类实例对象

public static Runtime getRuntime();

2.Runtime类的定义形式

Runtime类中有以下方法:
public long totalMemory();//返回所有可用内存空间
public long maxMemory();//返回最大可用内存空间
public long freeMemory();//返回空余内存空间

范例:观察内存大小:

public class TestDemo{
    
    public static void main(String[] args){
        Runtime runtime=Runtime.getRuntime();
        System.out.println("MAX="+runtime.maxMemory());
        System.out.println("Total="+runtime.totalMemory());
        System.out.println("FREE="+runtime.freeMemory());
    }   
}

在这里插入图片描述

如果一旦产生了过多垃圾,那么就会改变可用的内存空间大小,为此Runtime类里面提供了:public void gc();手动实现JVM的gc机制。

package TestDemo;


public class TestDemo{
    
    public static void main(String[] args){
        Runtime runtime=Runtime.getRuntime();
        System.out.println("MAX="+runtime.maxMemory());
        System.out.println("Total="+runtime.totalMemory());
        System.out.println("FREE="+runtime.freeMemory());
        String str="";
        for (int i = 0; i < 9000; i++) {
            str+=i;
        }
        System.out.println("MAX="+runtime.maxMemory());
        System.out.println("Total="+runtime.totalMemory());
        System.out.println("FREE="+runtime.freeMemory());
        runtime.gc();
        System.out.println("MAX="+runtime.maxMemory());
        System.out.println("Total="+runtime.totalMemory());
        System.out.println("FREE="+runtime.freeMemory());
    }   
}

在这里插入图片描述

面试题:请解释什么叫GC?如何处理?
GC(Garbage Collection) 垃圾收集器,指的是释放无用的内存空间,GC会由JVM不定期自动回收,(FGC,YGC,GC算法)或者调用Runtime的gc()方法。

Runtime类有一个更有意思的方法, 调用本机的可执行程序并且创建进程

public Process exec(String command)throws IOException

package TestDemo;


public class TestDemo{
    
    public static void main(String[] args)throws Exception{
        Runtime runtime=Runtime.getRuntime();
        Process pro=runtime.exec("mspaint.exe");//调用本机可执行程序
        Thread.sleep(5000);
        pro.destroy();//销毁进程
    }   
}

的确启动了本机的画图程序,5秒后关闭了

总结

1.Runtime类使用了单例设计模式,必须通过内部的getRuntime()方法获取实例化对象
2.Runtime类提供了gc()用于手动GC

1.YGC和FGC是什么

YGC :对新生代堆进行gc。频率比较高,因为大部分对象的存活寿命较短,在新生代里被回收。性能耗费较小。

FGC :全堆范围的gc。默认堆空间使用到达80%(可调整)的时候会触发fgc。以我们生产环境为例,一般比较少会触发fgc,有时10天或一周左右会有一次。

2.什么时候执行YGC和FGC

a.edn空间不足,执行 young gc

b.old空间不足,perm空间不足,调用方法System.gc() ,ygc时的悲观策略, dump live的内存信息时(jmap –dump:live),都会执行full gc

常见的GC回收算法及其含义

在探讨Java垃圾回收机制之前,我们首先应该记住一个单词:Stop-the-World。Stop-the-world意味着 JVM由于要执行GC而停止了应用程序的执行,并且这种情形会在任何一种GC算法中发生。当Stop-the-world发生时,除了GC所需的线程以外,所有线程都处于等待状态直到GC任务完成。事实上,GC优化很多时候就是指减少Stop-the-world发生的时间,从而使系统具有 高吞吐 、低停顿 的特点。

分代收集算法

对于一个大型的系统,当创建的对象和方法变量比较多时,堆内存中的对象也会比较多,如果逐一分析对象是否该回收,那么势必造成效率低下。分代收集算法是基于这样一个事实:不同的对象的生命周期(存活情况)是不一样的,而不同生命周期的对象位于堆中不同的区域,因此对堆内存不同区域采用不同的策略进行回收可以提高 JVM 的执行效率。当代商用虚拟机使用的都是分代收集算法:新生代对象存活率低,就采用复制算法;老年代存活率高,就用标记清除算法或者标记整理算法。Java堆内存一般可以分为新生代、老年代和永久代三个模块,如下图所示:

在这里插入图片描述1).新生代(Young Generation)

新生代的目标就是尽可能快速的收集掉那些生命周期短的对象,一般情况下,所有新生成的对象首先都是放在新生代的。新生代内存按照8:1:1的比例分为一个eden区和两个survivor(survivor0,survivor1)区,大部分对象在Eden区中生成。在进行垃圾回收时,先将eden区存活对象复制到survivor0区,然后清空eden区,当这个survivor0区也满了时,则将eden区和survivor0区存活对象复制到survivor1区,然后清空eden和这个survivor0区,此时survivor0区是空的,然后交换survivor0区和survivor1区的角色(即下次垃圾回收时会扫描Eden区和survivor1区),即保持survivor0区为空,如此往复。特别地,当survivor1区也不足以存放eden区和survivor0区的存活对象时,就将存活对象直接存放到老年代。如果老年代也满了,就会触发一次FullGC,也就是新生代、老年代都进行回收。注意,新生代发生的GC也叫做MinorGC,MinorGC发生频率比较高,不一定等 Eden区满了才触发。

2).老年代(Old Generation)

老年代存放的都是一些生命周期较长的对象,就像上面所叙述的那样,在新生代中经历了N次垃圾回收后仍然存活的对象就会被放到老年代中。此外,老年代的内存也比新生代大很多(大概比例是1:2),当老年代满时会触发Major GC(Full GC),老年代对象存活时间比较长,因此FullGC发生的频率比较低。

3).永久代(Permanent Generation)

永久代主要用于存放静态文件,如Java类、方法等。永久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如使用反射、动态代理、CGLib等bytecode框架时,在这种时候需要设置一个比较大的永久代空间来存放这些运行过程中新增的类。
  
小结:

在这里插入图片描述

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!