jvm,gc,static

来源:互联网 发布:淘宝卖stussy的正品店 编辑:程序博客网 时间:2024/04/26 03:23

面试的时候一直有问jvm和垃圾回收的问题,看了点东西,汇总一下。

首先盗个图

上图就是JVM的内部结构,有两个系统,包括CLASS LOADER和EXECUTION ENGINE两个子系统,以及RUNTIME DATA AREA和NATIVE INTERFACE两个组件。

  • CLASS LOADER:
    主要负责装载.class文件中的内容到RUNTIME DATA AREA中的METHOD AREA(方法区)中。

  • EXECUTION ENGINE:
    主要负责执行。jvm的不同主要就是因为EXECUTION ENGINE不同。

  • NATIVE INTERFACE:
    与native libraries交互,是其它编程语言交互的接口。

  • RUNTIME DATA AREA:
    这就是我们常说的jbvm内存了。包含的区域有五部分:

    1. METHOD AREA(方法区)
      被装载的class的信息存储在Method area的内存中。当虚拟机装载某个类型时,它使用类装载器定位相应的class文件,然后读入这个class文件内容并把它传输到虚拟机中。

    2. HEAP(堆)
      一个Java虚拟实例中只存在一个堆空间,实例化的对象是保存在堆中的。

    3. JAVA STACK(栈)
      虚拟机只会直接对Java stack执行两种操作:以帧为单位的压栈或出栈。引用(可以理解为实例化后的对象的指针)是保存在栈内存中的。

    4. NATIVE METHOD STACK(本地方法栈)

    5. Program Counter(程序计数器)

关于GC机制,在jvm中,将对象分为YOUNG,OLD,PERMANENT。

其中将young主要用来初始化实例,如果实例的生命周期长的话就会放入old中存放。
而permanent区域则主要存放静态文件,如类,方法等。

young和old都是在堆内存中的,而perm则是在方法区的。

我们经常说的jvm垃圾回收则主要是指堆内存回收。


关于静态成员:static

静态方法和静态变量都是放在perm区域的,无需实例化对应的对象即可访问。

public class Main1 {    /**     * @param args     */    public static void main(String[] args) {        // TODO Auto-generated method stub         printStatic();         //无需实例化Main1类即可调用static方法//       printNoStatic();       //未实例化类,想要调用非static方法会报错         Main1 m = new Main1();         m.printNoStatic();     //只有实例化后才能调用非static方法         //除了方法,对于变量也同理。         System.out.println(x);         System.out.println(m.y);    }    static int x=1;    int y=0;    public static void printStatic(){        System.out.println("static");    }    public void printNoStatic(){        System.out.println("noStatic");    }}

从上面可以看出,无需实例化即可调用static的成员。

那么这有什么缺点呢?
上面说了,static会存入perm区域的内存中,而这部分内存不会被动态的回收。如果定义了过多的static成员,就会导致内存利用率过低,内存使用量太大。

更多请点击:http://www.tuicool.com/articles/vuyiMn

0 0
原创粉丝点击