Java 的 jvm 与 gc 概述
1.JVM 基础
JVM 就是 java 虚拟机,每一个 JVM 都包括堆,栈,本地方法栈、方法区,指令计数器及其他隐含寄存器。堆:负责存储对象实例。栈:存储基本类型和对象的引用。方法区:存放着类的静态变量,常亮,类的信息等。本地方法栈:与栈相类似,只不过存放的是方法。举例:
此时会向栈中压入一个叫 address 栈,在堆中开辟一块内存空间存放 beijing,其中 address 存放着 beijing 这块内存空间的地址。而这样有什么好处呢,当还有另一个对象也叫 beijing 时我们把内存地址给他就好了,不用额外开辟另一块内存空间了。
2.类的加载
当了解 JVM 结构之后,就时 JVM 的运行流程。
我们运行程序,就时运行一个个编译好的类,首先类加载器使用二进制的方式先加载类,放于方法区内,然后在堆上新建一个 class 对象,封装类的数据结构,同时提供接口供方法区调用,在栈中存放着类的声名,这样我们完成了类的加载,然后在经过其处理就可以使用类了。(具体类加载的源码和原理请参考-http://www.cnblogs.com/ityouknow/p/5603287.html)
3.GC
如果内存空间满了改怎么办,JVM 提供了 GC-也就是垃圾回收机制。当内存溢出自动进行垃圾处理。一般都是堆发生垃圾回收。而堆被分为了三部分分别是新生代 ,年老代,持久带,新生代又被分为 Eden、Survivor1、Survivor2 这三块,当一个对象被新建后会被放入 eden 中(较大的直接放入年老代中),当 eden 被存满后会发生 minor GC,此时 eden 会将内存中不用的空间清除并把剩余的数据放入 Survivor1,当下一次 eden 被存满后,重复上次操作,eden 和 Survivor1 中数据会一起存放进 Survivor2 中,直到 Survivor1 或 Survivor2 存放满,这时会把存放满的 Survivor1 或 Survivor2 数据存进年老代中,而当年老代被存满后会发生 full gc 此时会清理年老代的内存。
4.垃圾回收算法
垃圾回收分为三种算法
1.标记-清除
就时在堆中查找每块内存是否有栈在使用这块堆内存,没有就清理掉,但是这样会产生大量的磁盘碎片。
2.复制
为了解决第一种问题。把内存分为两部分,把正在使用的内存复制到另一块内存中,不过这样的缺点是需要两倍的空间。
3.标记-整理
此方法采用了以上两种方法的特点,此方法分为两个阶段 1.标记出没被使用的内存并清除掉。2.将剩余的内存空间集中到连续的空间上。
评论