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

浙公网安备 33010602011771号