jvm结构 和GC回收机制

、jvm结构:

从上边的图可以看出,jvm结构主要分为4大块(右边的图表示从java源代码到jvm执行的过程)。

1,类加载器 classloader:jvm启动时或者类运行时,将所需要的类加载到jvm中(jvm将javac编译好的class文件加载的jvm中)。

2,内存区:主要是jvm运行时操作所分配的分配内存。

3,执行引擎:负责执行class文件中包含的字节码指令。

4,本地库接口:本地有c或者c++实现的方法。

jvm 存储空间主要分为5大区域。

共享区(共享区的资源是整个进程都可以使用的)

 heap 堆:用来存放所有的实例或者对象。即 new 出来的对象都是存在堆上的。 

 method area 方法区:用来存储类结构信息的地方,常量池、静态变量和构造函数。

私有区(每创建一个线程就会创建一个私有区,包含jvm stack、pc register、natice method stack)

栈区和线程是一一对应的,线程生栈生,线程灭栈灭,当线程结束后,随之生成的栈会自动释放所有内存。

 java stack 栈:java栈总是和线程关联在一起的。每当声明一个线程的时候,jvm就会为这个线程创建一个对应的java栈。线程每调用一个方法,就会创建一个栈帧,栈帧用来存储局部变量、操作栈、方法返回值等信息。

         每一个方法从调用到执行完成,就对应着栈帧的入栈到出栈。

 pc register 程序计数器:用于保存当前执行线程的内存地址。jvm是多线程的,线程轮流工作,当线程切换的时候,需要有记录器记录当前线程的执行信息(中断位置),在线程切换回来的时候继续执行。

 native method stack 本地方法栈:作用和java stack类似,不过事在调用native方法的时候,用来存储本地方法的一些信息。

 

二、内存分配

   java 的内存分配机制和c/c++不一样,c/c++是通过malloc进行系统调用,而系统调用发生在内核空间,每次都要中断进行切换,这需要一定的开销。而java虚拟机是先直接在内存中分配一大块空间,在new对象的时候,

对内存进行分配和释放,减少了系统调用次数,节省了一定开销。类似于内存池的概念。

  我们在程序中变量存储在栈中,引用类型值存放在堆中,引用类型地址存放在占中,在传参的时候,参数传递的是引用类型的地址,当我们对引用类型进行操作的时候,会直接修改引用地址所在堆上的值。

   是顺序分配的,而且定长,不存在回收问题; 是随机分配的,不定长度,所以需要分配和回收;

  java内存申请一般有两种方式:

  静态内存:1,在程序运行时由编译器分配的内存,内存是固定的,比如 int变量

          2,无需占用cpu资源,自动释放内存空间

          3,存放在栈中

       4,按计划分配,由编译器负责

  动态内存:1,在执行期才知道要分配存储空间大小,或者空间太大,栈上无法保存。比如 java对象。

       2,分配和释放都需要占用cpu资源。

       3,存放在堆上。

       4,按需分配,由程序员负责。

       5,分配内存需要指针和引用类型支持。

三、垃圾检测 回收算法

  垃圾收集器一般要完成两件事:1 检测垃圾,2 回收垃圾

  怎么检测垃圾?

  引用计数法:给对象加上引用计数器,每添加一个地方引用,计数器+1,引用失效就-1。

  但是 如果 a 对象和 b对象相互引用,并无其他地方使用它们,这两个对象就不适合引用计数法了。

  可达性分析算法:以根集对象为起点进行搜索,若果对象不可达,即为垃圾对象。根集对象一般包括 java栈中引用对象、方法区常量池中引用的对象、本地方法引用的对象

  怎么回收垃圾?

  1,标记-清除(mark-sweep)

    标记所有需要回收的对象,然后一次性清除。

    不足:会产生大量垃圾碎片,效率低。

        

  2,复制(copying)

    此方法将内存划分为两个相等的区域,当垃圾回收时会遍历当前使用区域,把使用中的对象复制到另一个区域。复制成本较小(只复制使用中对象),效率高,不会出现碎片问题。

    不足:内存浪费。

    

  3,标记-整理(mark-compact)

    首先,标记所有引用对象,遍历整个堆,清除未引用对象,并且把存活对象压缩排序。

    

  4,分代收集算法

    不同对象的声明周期是不一样的,根据生命周期长短采用不同的方式,以提高收集效率。

  如何区分内存的生命周期?

  1,年轻代(young generation)

    所有新对象产生的地方,分为三个区域,Eden和另个servivor(s1,s2)。当Eden被填满的时候,就会执行minor gc,并且把存活下来的对象放入s1中,在s1中 minor gc 还会再坚持一遍所有对象,将存活的对象放入s2中。

  这样在一段时间内总是有一个空的servivor空间(s1或者s2),当经过多次gc周期后依然存活的对象,就会转移到老年代空间中。

  2,老年代(old generation)

    在年轻代中经过n次回收后仍然没有清除的对象,就会被放入老年代中。

  3,持久代(permanent generation)

    用于存放静态文件,比如 java类、方法

  

 

四、垃圾收集器

  垃圾收集算法,只是垃圾收集的方法论,而实现了这些方法的就是垃圾收集器。

 

原文地址:https://blog.csdn.net/moneyshi/article/details/53033577

 

posted @ 2018-12-05 14:26  诗错り亦染  阅读(135)  评论(0)    收藏  举报