JVM
- 栈:对象的引用,即地址,等号左边的
- 堆:new出来的对象,等号右边的
- 方法区:常量,静态变量,类的信息
- 本地方法栈:native方法使用,C语言相关
- 程序计数器:程序运行的位置
字符串常量池在1.7之前(不含1.7)是在方法区,1.7之后在堆中
GC
因为堆和方法区是多线程共享的,某段程序运行结束并不能确定是否有其他线程还在使用该内容,不能自动删除,所以要利用GC来回收这些内存,即GC的目标是堆和方法区。
根搜索
用来判断一个对象是否可以回收,是否没有被引用。
根是搜索的起点,可以作为根的:
- 被栈上的引用直接或间接引用的对象
- 被本地方法栈上的引用直接或间接引用的对象
- 被方法区的静态变量直接或间接引用的对象
被搜索到的对象都是存活着的,不能回收
标记-清除
先用根搜索算法标记存活的对象,再将没有被标记的对象清除
缺点:会产生很多内存碎片
标记-整理
在标记-清除的基础上,整理内存碎片,将存活的对象整理集中在一起
缺点:需要移动对象,性能较低
复制
将堆分成两个区,每次使用一个区,内存满时,根搜索并标记后,将存活的对象复制到另一个区
缺点:需要更大的内存空间
当今的GC
将堆分为了年轻区和老年区,年轻区又分为伊甸区和两个幸存区。
伊甸区是新对象出生的地方,即刚被new出来时,当伊甸区满时触发minor GC,用根搜索标记存活的对象,将存活的对象复制到幸存区1,清空伊甸区,伊甸区再满时触发下次minor GC,用根搜索标记标伊甸区和幸存区1记存活的对象,将存活的对象复制到幸存区2,清空伊甸区和幸存区1,如此交替。
minor GC达到一定次数时,将幸存区的对象复制到老年区,当老年区满的时候会触发full GC,此时java程序暂停,对整个堆区全力进行垃圾回收,采用标记-清除,或标记-整理
新java版本采用G1算法
JVM参数配置
JVM中参数有3类:
-: 标准参数,所有的JVM实现都必须实现这些参数的功能,而且向后兼容-X: 非标准参数,默认JVM实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容-XX: 非稳定参数,各个JVM实现会有所不同,将来可能会随时取消
标准参数
-version:查看java版本
java -version
-jar: 执行jar包程序-client: 设置JVM使用client模式,启动很快,但性能和内存管理效率并不高。串行GC-server: 使用server模式,启动速度虽然慢(比client模式慢10%左右),但是性能和内存管理效率很高,适用于服务器,生产环境。并行GC-classpath/-cp: JVM加载和搜索文件的目录路径-verbose:class: 输出JVM载入类的相关信息-verbose:gc: 输出每次GC的相关情况-verbose:jni: 输出native方法调用的相关情况
非标准参数
输入java -X命令,能够获得当前JVM支持的所有非标准参数列表
-Xmn: 年轻代的内存大小,相当于同时设置了-XX:NewSize和-XX:MaxNewSize-Xms: 堆的初始内存大小,也是堆的最小内存值-Xmx: 堆的内存最大值-Xss: 每个线程的栈内存-Xprof: 跟踪正运行的程序,并将跟踪数据在标准输出-Xnoclassgc: 关闭针对class的GC功能-Xincgc: 开启增量gc(默认为关闭),有助于减少长时间GC时应用程序出现的停顿;但由于可能和应用程序并发执行,所以会降低CPU对应用的处理能力-Xloggc:file: 将每次GC事件的相关情况记录到一个文件中
非稳定参数
非稳定参数有如下格式:
-XX:+<option>: 启用选项-XX:-<option>: 不启用选项-XX:<option>=<value>: 给选项设置一个数字类型值,可跟单位,或字符串类型值
| 参数及其默认值 | 描述 |
|---|---|
| -XX:NewSize=2.125m | 年轻代初始内存的大小 |
| -XX:MaxNewSize | 年轻代最大内存的大小 |
| -XX:PermSize=64m | 方法区分配的初始内存 |
| -XX:MaxPermSize=64m | 方法区所能占用的最大内存 |
| -XX:ThreadStackSize=512 | 线程栈大小,若为0则使用系统默认值,和-Xss作用一样 |
| -XX:MaxTenuringThreshold=15 | 对象在年轻代幸存区切换的次数,即MinorGC的次数,大于该值会进入老年代(年龄阈值) |
| -XX:MaxHeapFreeRatio=70 | GC后java堆中空闲量占的最大比例,大于该值,则堆内存会减少 |
| -XX:MinHeapFreeRatio=40 | GC后java堆中空闲量占的最小比例,小于该值,则堆内存会增加 |
| -XX:PretenureSizeThreshold | 大于该值的对象直接晋升入老年代 |
| -XX:NewRatio=2 | 老年代和年轻代内存比例 |
| -XX:SurvivorRatio=8 | 伊甸区和幸存区的比例,即Eden:Survivor1:Survivor2=8:1:1 |