java堆结构和垃圾回收
JVM内存结构和垃圾回收
一、JVM垃圾收集算法
1、引用计数算法
每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。
此方法简单,无法解决对象互相循环引用的问题,还有一个问题是如何解决精准计数。
2、根搜索算法
从GC Root开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Root没有任何引用链相连时,
则证明此对象是不可用的,不可达对象。
在java语言中,GC Root包括:
虚拟机栈中引用的对象
方法区中类静态属性实体引用的对象
方法区中常量引用的对象
本地方法栈中JNI引用的对象
二、垃圾回收算法
1、复制算法(Copying)
复制算法采用从根集合扫描,并将存活对象复制到一块新的,没有使用过的空间中,但这种算法当控件存活的对象比较少时,
极为高效,但是带来的成本是需要一块内存交换空间用于进行对象的移动。
此算法用于新生代内存回收,从E区回收到SO或者S1
2、标记清除算法(Mark-Sweep)
标记-清除算法采用从根集合进行扫描,对存活的对象标记,标记完毕后,再扫描整个空间中未被标记的对象,进行回收。
标记-清除算法不需要进行对象的移动,并且仅对不存活的对象进行处理,在存活对象比较多的情况下极为高效,
但由于标记-清除算法直接回收不存活的对象,因此会造成内存碎片
3、标记整理压缩算法(Mark-Compace)
标记-整理算法采用标记-清除算法一样的方式进行对象标记,但在清除时不同,再回收不存活的对象占用的空间后,会将
所有的存活对象往左端空闲空间移动,并更新对应的指针,标记-整理算法是在标记清除算法的基础上,又进行了对象的移动,
因此成本更高,但是却解决了内存碎片的问题。
串行回收(serial收集器):GC单线程内存回收、会暂停所有用户线程
1、是一个单线程的收集器,只能使用一个CPU或者一条线程去完成垃圾收集;在进行垃圾收集时,必须暂停所有其他工作线程,直到收集完成;
2、缺点:Stop-The-World
3、优势:简单,对于单CPU的情况,由于没有多线程交互开销,反而可以更高效,是Client模式下默认的新生代收集器。
使用方法:
-XX:+UseSerialGC来开启
Serial New+Serial Old的收集器组合进行内存回收
使用复制算法(新生代)/标记压缩算法(老年代)
独占式的垃圾回收(一个线程进行GC,串行,其他工作线程暂停)
并行回收(Parallel收集器):多个gc线程并行工作,但此时用户线程是暂停的
并行回收器也是独占式的回收器,在收集过程中应用程序会全部暂停,但由于并行回收器使用多线程进行垃圾回收,因此,在并发能力比较
强的CPU上,它产生的停顿时间要短于串行回收器,而在单CPU或者并发能力较弱的系统中,并行回收器的效果不会比串行回收器好,由于多线程
的压力,它的实际表现很可能比串行回收器差
使用方法:
-XX:+UseParNewGC开启
新生代使用并行回收收集器,老年代使用串行收集器
-XX:ParallelGCThreads指定线程数
默认是CPU的核心数,过多的线程数会影响垃圾收集性能
使用复制算法
并行的、独占式的垃圾回收器
新生代Parallel Scavenge回收器
1、吞吐量优先回收器
关注CPU吞吐量,即运行用户代码的时间/总时间,比如:JVM运行100分钟,其中运行用户代码99分钟,垃圾收集1分钟,则吞吐量是99%,
这种收集器能最高效率的利用CPU,适合运行后台运算
2、-XX:+UseParallelGC开启
使用Parallel Scavenge+Serial Old的收集器组合进行垃圾回收,这也是Server模式下的默认值
3、-XX:GCTimeRatio
设置用户执行时间占总时间的比例,默认99,即1%的时间用来进行垃圾回收
4、-XX:MaxGCPauseMillis
设置GC的最大停顿时间
5、使用复制算法
老年代Parallel Old回收器
1、-XX:+UseParallelOldGC开启
使用Parallel Scavenge+Parallel Old的收集器组合进行垃圾回收
2、使用标记整理算法
3、并行的、独占式的垃圾回收器
并发回收(CMS收集器):用户线程与GC线程同时执行(不一定是并行,可能交替,但总体上是同时执行的),不需要停顿用户线程
在CMS中用户线程还是需要停顿的,只是非常短,GC线程在另一个CPU上执行
运作过程分为4个阶段:
初始标记(CMS initial mark):值标记GC Roots能直接关联到的对象
并发标记(CMS concurrent mark):进行GC RootsTracing的过程
重新标记(CMS remark):修正并发标记期间因用户程序继续运行而导致标记发生改变的那一部分对象的标记
并发清除(CMS concurrent sweep)
其中标记和重新标记两个阶段仍然需要Stop-The-World,整个过程中耗时最长的并发标记和并发清除过程中收集器都可以和用户线程一起工作。
1、标记-清除算法
同时它又是一个使用多线程并发回收的垃圾收集器
2、-XX:ParallelCMSTheads
手工设定CMS的线程数量,CMS默认启动的线程数是(ParallelGCTheads+3)/4
3、-XX:+UseConcMarkSweepGC开启
使用ParNew+CMS+Serial Old的收集器组合进行内存回收,Serial Old作为CMS出现"Concurrent Mode Failure"失败后的后备收集器使用
4、-XX:CMSInitiatingOccupancyFraction
设置CMS收集器在老年代空间被使用多少后触发垃圾收集,默认为68%,仅在CMS收集器时有效,-XX:CMSInitiatingOccupancyFraction=70
5、-XX:+UseCMSCompactAtFullCollection
由于CMS收集器会产生碎片,此参数设置在垃圾收集器后是否需要一次内存碎片整理过程,仅在CMS收集器时有效
6、-XX:+CMSFullGCBeforeCompaction
设置CMS收集器在进行若干次垃圾收集后再进行一次内存碎片整理过程,通常与UseCMSCompactAtFullCollection参数一起使用
7、-XX:CMSInitiatingPermOccupancyFraction
设置Perm Gen使用达到多少比率时出发,默认92%
HotSpot垃圾回收器
java堆结构和垃圾回收的更多相关文章
- Java 堆和栈 垃圾回收 2015/9/16
http://www.cnblogs.com/whgw/archive/2011/09/29/2194997.html Java内存: 1.堆内存:基本类型的变量和对象的引用变量. 2.栈内存:由ne ...
- Java内存管理 -JVM 垃圾回收
版权声明:本文为博主原创文章,未经博主允许不得转载 一.概述 相比起C和C++的自己回收内存,JAVA要方便得多,因为JVM会为我们自动分配内存以及回收内存. 在之前的JVM 之内存管理 中,我们介绍 ...
- 巩固java(二)----JVM堆内存结构及垃圾回收机制
前言: 我们在运行程序时,有时会碰到内存溢出(OutOfMemoryError)的问题,为了解决这种问题,我们有必要了解JVM的内存结构和垃圾回收机制. 正文: 1.JVM堆内存结构 ...
- java基础(一):谈谈java内存管理与垃圾回收机制
看了很多java内存管理的文章或者博客,写的要么笼统,要么划分的不正确,且很多文章都千篇一律.例如部分地方将jvm笼统的分为堆.栈.程序计数器,这么分太过于笼统,无法清晰的阐述java的内存管理模型: ...
- Java基础教程:垃圾回收
Java基础教程:垃圾回收 垃圾回收 垃圾回收(Garbage Collection,GC),顾名思义是释放垃圾占用的空间,防止内存泄漏.有效的使用可以使用的内存,对内存堆中已经死亡的或者长时间没有使 ...
- .net学习之类与对象、new关键字、构造函数、常量和只读变量、枚举、结构、垃圾回收、静态成员、静态类等
1.类与对象的关系类是对一类事务的统称,是抽象的,不能拿来直接使用,比如汽车,没有具体指哪一辆汽车对象是一个具体存在的,看的见,摸得着的,可以拿来直接使用,比如我家的那辆刚刚买的新汽车,就是具体的对象 ...
- 《深入理解 Java 虚拟机》学习 -- 垃圾回收算法
<深入理解 Java 虚拟机>学习 -- 垃圾回收算法 1. 说明 程序计数器,虚拟机栈,本地方法栈三个区域随线程而生,随线程而灭,这几个区域的内存分配和回收都具备确定性 Java 堆和方 ...
- Java其实不支持垃圾回收
Java其实不支持垃圾回收.如果真的支持的话,大多数Java程序在运行的一开始就应该把程序本身删除,因为这些程序本身就是垃圾. // TODO: This is a 分割线. Please no ...
- JVM内存结构、垃圾回收那点事
翻看电脑的文件夹,无意看到了9月份在公司做的一次分享,浏览了一下"婆婆特",发现自己在ppt上的写的引导性问题自己也不能确切的回答出来,哎,知识这东西,平时不常用的没些日子就生疏了 ...
随机推荐
- php扩展安装
[root@129-2-10-2 src]# cat kuozhan.sh #!/bin/bash###install redis extend #########cd /usr/local/srct ...
- C++ 类的继承三(继承中的构造与析构)
//继承中的构造与析构 #include<iostream> using namespace std; /* 继承中的构造析构调用原则 1.子类对象在创建时会首先调用父类的构造函数 2.父 ...
- sql one
查询的话 子查询什么的都很正常 添加的话 尽量把东西都添加在一个表单里 这是源头 有个这个方便的源头 查询和删除都会方便很多 组建一个网站,不可避免的要进行调试,有些功能需要添加或者删除,对于后台来讲 ...
- 003Maven_Maven核心概念
Maven核心概念 Maven插件 Maven的核心仅仅定义了抽象的生命周期,具体的任务都是交由插件完成的每个插件都能实现多个功能,每个功能就是一个插件目标 Maven的生命周期与插件目标相互绑定,以 ...
- Windows下基于eclipse的Spark应用开发环境搭建
原创文章,转载请注明: 转载自www.cnblogs.com/tovin/p/3822985.html 一.软件下载 maven下载安装 :http://10.100.209.243/share/so ...
- 如何在ChemDraw中打出符号π
很多人日常使用ChemDraw是一款非常优秀的化学绘图软件,在其绘制化学结构式或者反应式的过程中,常常需要添加各种符号.比如有的用户会需要输入希腊字符π,但是不知道用什么方法添加.本教程就来给大家介绍 ...
- VC++ 监视文件(夹)
参考:http://www.cnblogs.com/fangkm/archive/2009/03/31/1426526.html WinFileSystemMonitor.h C++ Code 1 ...
- hdu 1513(dp+滚动数组)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1513 思路:n这么大,可以采用滚动数组,然后就是求原串和反串的LCS了. #include<io ...
- Android模拟器基本使用和常用工具介绍
注:其中部分内容参考网上资源 1.Android模拟器介绍 Android中提供了一个模拟器来模拟ARM核的移动设备.Android的模拟器是基于QEMU开发的,QEMU是一个有名的开源虚拟机项目(详 ...
- android 开发 - 结束所有activity
每一个activity都有自己的生命周期,被打开了最终就要被关闭. 四种结束当前的activity方法 //关闭当前activity方法一 finish(); //关闭当前界面方法二 android. ...