JVM垃圾回收(GC)原理
一.基本垃圾回收算法
1.引用计数(Reference Counting)
比较古老的回收算法。原理是此对象有一个引用则增加一个引用计数,删除一个引用则较少一个引用计数。垃圾回收时,只回收引用计数为0的对象。此算法最致命的是无法处理互相引用的问题。
2.标记-清除(Mark-Sweep)
此算法执行分两个阶段。第一个阶段是从根节点开始标记所有被引用的对象;第二个阶段遍历整个堆,把未标记的对象清除。此算法需要暂停整个应用,并且会产生内存碎片。
3.复制(Copying)
此算法把内存空间划分为2个相同的区域,每次只使用其中一个区域。垃圾回收时,区域A从根开始访问每一个关联的正在使用的对象,并且把正在使用的对象复制到另外一个区域B,然后回收区域A中所有对象。此算法只访问活跃对象,所以遍历空间成本低,但是此算法的缺点也很明显,就是需要2倍内存空间。
4.标记-整理(Mark-Compact)
此算法也是分两个阶段。第一个阶段是从根节点开始标记所有被引用的对象;第二阶段遍历整个堆,清除未被标记的对象并且把标记的对象(正在使用的对象)压缩到一起按顺序存放。此算法避免了“标记-清除”算法中的内存碎片问题,并且也避免了“复制”算法的空间问题。
二.JVM内存模型。

1.基础概念
(1)JVM内存限制(最大值):
JVM内存的最大值跟操作系统有很大的关系。简单的说32位操作系统虽然可控内存有4GB,但是操作系统会给一个限制,Windows下为2GB,Linux下为3GB,而64位及以上的操作系统没有限制。
(2)JVM默认内存分配:
JVM初始分配的内存由-Xms指定:默认是物理内存的1/64但是小于1GB。
JVM最大分配的内存有-Xmx指定:默认是物理内存的1/4但是小于1GB。
(3)JVM内存自动调整:
默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx限制,可以由-XX:MinHeapFreeRatio=指定。
默认空余堆内存大于70%时,JVM就是减少堆直到-Xms限制,可以由-XX:MaxHeapFreeRatio=指定。
但是服务器一般都设置-Xms、-Xmx相等以避免每次gc后都调整堆的大小,所以这两个参数一般没什么作用。
2.堆(Heap)和非堆(Non-heap)内存
(1)堆(Heap)

(2)非堆(Non-heap)

参考文档:
http://www.cnblogs.com/redcreen/tag/jvm/
http://chenchendefeng.iteye.com/blog/455883
http://www.open-open.com/lib/view/open1324736648468.html
http://vanadiumlin.iteye.com/blog/1267857
JVM参数:
1、JVM堆相关参数
| 参数 | 说明 | 备注 |
| -Xmx |
设置最大堆内存 |
一般-Xmx与-Xms设置相同 |
| -Xms |
设置最小堆内存 |
|
| -Xmn |
设置新生代内存大小 |
-Xmn等同于设置了相同的-XX:NewSize与-XX:MaxNewSize |
| -XX:NewSize |
设置新生代初始大小 |
|
| -XX:MaxNewSize | 设置新生代最大值 | |
| -XX:PermSize | 设置持久代初始大小 | 用于JDK8 之前 |
| -XX:MaxPermSize | 设置持久代的最大值 | 用于JDK8 之前 |
| -XX:MetaspaceSize | 设置持久代初始大小 | 用于JDK8之后,包含JDK8 |
| -XX:MaxMetaspaceSize | 设置持久代的最大值 | 用于JDK8之后,包含JDK8 |
| -Xss | 设置线程栈的大小 | 线程栈所占内存不是堆内存,是操作系统内存减去堆内存 |
| -XX:MinHeapFreeRatio | 设置堆空间最小空闲比例 | 当堆空间的空闲内存小于这个数值时,JVM便会扩展堆空间,默认值40 |
| -XX:MaxHeapFreeRatio | 设置堆空间最大空闲比例 | 当堆空间的空闲内存大于这个数值时,JVM便会压缩堆空间,得到一个较小的堆,默认值70 |
| -XX:NewRatio | 设置老年代与新生代比例 | 等于老年代大小除以新生代大小 |
| -XX:SurviorRatio | 新生代中Eden与survivor区的比例 | |
| -XX:TargetSurvivorRatio | 设置survivor区的使用率 | 当survivor区的空间使用率达到这个数值时,会将对象送入老年代,默认值50,最高90 |
2、JVM垃圾收集器相关参数



| 参数 | 说明 | 备注 |
| -XX:+CMSClassUnLoadingEnabled | 允许对类元数据进行回收 | |
| -XX:CMSInitiatingPermOccupancyFraction | 当永久代占用率达到这一百分比时,启动CMS回收 | 前提是-XX:+CMSClassUnLoadingEnabled激活了 |
| -XX:UseCMSInitiatingOccupancyOnly | 表示只在达到阈值的时候,才进行CMS回收 | |
| -XX:+CMSIncrementalMode | 使用增量模式,比较适合单CPU |
3、实用JVM参数
| 参数 | 说明 | 备注 |
| -XX:+HeapDumpOnOutOfMemoryError | 当程序发生OOM时,导出应用程序当前堆快照 | |
| -XX:HeapDumpPath | 可以指定堆快照的保存位置 |
-XX:+HeapDumpOnOutOfMemoryError |
| -XX:OnOutOfMemoryError | 系统发生OOM错误时可运行一段第三方脚本 |
-XX:OnOutOfMemoryError=c:\reset.bat |
| -verbose:gc | 获取gc信息 | |
| -XX:+PrintGC | 获取gc信息 | |
| -XX:+PrintGCDetails | 获取gc详细信息 | |
| -XX:+PrintHeapAtGC | gc时打印详细的堆信息 | |
| -Xloggc | 将gc信息保存到文件 | -Xloggc:/Users/yangyu/Downloads/gc.log |
| -XX:+TraceClassLoading | 用于跟踪类加载情况 | |
| -XX:+TraceClassUnLoading | 用于跟踪类卸载情况 | |
| -verbose:class | 用于跟踪类加载和卸载情况 | |
| -XX:+DisableExplicitGC | 用于禁止显示的gc操作 | 也就是禁止代码里面的System.gc() |
JVM垃圾回收(GC)原理的更多相关文章
- 性能测试三十五:jvm垃圾回收-GC
垃圾回收-GC 三个问题 哪些内存需要回收? 什么时候回收? 如何回收? YoungGC和FullGC: 新生代引发的GC叫YoungGC 老年代引发的GC叫FullGC FullGC会引起整个Jvm ...
- .NET垃圾回收(GC)原理
作为.NET进阶内容的一部分,垃圾回收器(简称GC)是必须了解的内容.本着“通俗易懂”的原则,本文将解释CLR中垃圾回收器的工作原理. 基础知识 托管堆(Managed Heap) 先来看MSDN的解 ...
- JVM 垃圾回收GC Roots Tracing
1.跟搜索算法: JVM中对内存进行回收时,需要判断对象是否仍在使用中,可以通过GC Roots Tracing辨别. 定义: 通过一系列名为”GCRoots”的对象作为起始点,从这个节点向下搜索,搜 ...
- JVM垃圾回收(GC)流程
/* 首先介绍一下JVM中堆内存的组成: JVM堆内存主要由三部分组成: (1)新生代: 伊甸园区,存活区,伸缩区 (2)老年代: 老年区,伸缩区 (3)元空间(永久代): 元空间,伸缩区 注意:JD ...
- JVM垃圾回收——GC
一.JVM内存分配与回收 下图为堆内存结构图(注意:元数据区(MetaData )实际上不属于堆): 1.对象优先在Eden区分配 大多数情况下,对象在新生代中Eden区分配.当Eden区没有足够空间 ...
- JVM垃圾回收GC
1.堆的分代和区域 (年轻代)Young Generation(eden.s0.s1 space) Minor GC (老年代)Old Generation (Tenured space) ...
- JVM—垃圾回收GC算法
1 GC算法简介 算法 特点 标记-清除 分为"标记"和"清除"两个阶段 复制 可以解决效率问题,将可用的内存按容量划分为大小相等的两块. 标记-整理 先标记. ...
- JVM 及 垃圾回收机制原理
JVM Java 虚拟机 Java 虚拟机(Java virtual machine,JVM)是运行 Java 程序必不可少的机制.JVM实现了Java语言最重要的特征:即平台无关性.原理:编译后的 ...
- jvm垃圾回收原理(转)
原文链接:jvm垃圾回收原理 在jvm中堆空间划分为三个代:年轻代(Young Generation).年老代(Old Generation)和永久代(Permanent Generation).年轻 ...
- Java:JVM垃圾回收(GC)机制
JVM垃圾回收算法 1.标记清除(Mark-Sweep) 原理: 从根集合节点进行扫描,标记出所有的存活对象,最后扫描整个内存空间并清除没有标记的对象(即死亡对象)适用场合: 存活对象较多的情况下比较 ...
随机推荐
- 如何在 ASP.NET MVC 中集成 AngularJS(3)
今天来为大家介绍如何在 ASP.NET MVC 中集成 AngularJS 的最后一部分内容. 调试路由表 - HTML 缓存清除 就在我以为示例应用程序完成之后,我意识到,我必须提供两个版本的路由表 ...
- 工作任务:模拟淘宝登录和购物车功能:使用cookie记录登录名,下次登录时能够记得上次的登录名,使用cookie模拟购物车功能,使用session记住登录信息并验证是否登录,防止利用url打开网站,并实现退出登录功能
登入界面<% Cookie[] cks =request.getCookies(); String str=null; for(Cookie ck:cks) { if(ck.getName(). ...
- Spill data to tempdb
查看Execution Plan时,在Sort Operator上,发现一个Warning:Operator used tempdb to spill data during execution wi ...
- SSIS Data Flow优化
一,数据流设计优化 数据流有两个特性:流和在内存缓冲区中处理数据,根据数据流的这两个特性,对数据流进行优化. 1,流,同时对数据进行提取,转换和加载操作 流,就是在source提取数据时,转换组件处理 ...
- javascript运动系列第二篇——变速运动
× 目录 [1]准备工作 [2]加速运动 [3]重力运动[4]减速运动[5]缓冲运动[6]加减速运动[7]往复运动[8]变速函数 前面的话 前面介绍过匀速运动的实现及注意事项,本文在匀速运动的基础上, ...
- Android Studio安装以及Fetching android sdk component information超时的解决方案
转载:http://www.cnblogs.com/sonyi/p/4154797.html 在经过两年的开发之本后,Google 公司终于发布了 Android Studio 1.0,喜欢折腾的童鞋 ...
- java获取类的信息
关键技术剖析 1.java.lang.reflect包实现了java的反射机制,在使用反射机制时,需要导入该包. 2.Class类的forName方法能够根据类名加载类,获得类的Class对象. Cl ...
- 【tomcat】不同域名解析到同一tomcat不同项目上
问题: 1. 有多个域名,想输入的每个域名只能访问其中的一个项目 2. 这些项目都部署在同一个tomcat上的 解决步骤: 1.首先把所有域名都解析到这台服务器上,解析时只能填写ip地址,不 ...
- Lua 学习笔记(八)错误(error)
Lua所遇到的任何未预期条件都会引发一个错误.因此在发生错误时不能简单的崩溃或着退出,而是结束当前程序块并返回应用程序.当错误引发时进行恰当的处理是最合适的,然而这个阶段伴随着错误的捕获.错误的处理. ...
- 如何用 js 获取table 或者其他块状标签的 宽和高
这个比较简单,总体思想,标签标记一个id,js获取id,就能用它的属性了.介绍两种方法.请看下面代码. 第一种 <script> function width_table_all() { ...