Java内存模型

总的来说就分为两个区域,堆内存(Heap)和非堆内存(No-Heap),非堆内存又称为永久代(Permanent),永久的意思其实是针对于垃圾回收器来说的,表示这部分内容不需要回收。在新的JDK8中,这部分的名称已经不叫Permanent了,改成更好理解的Metaspace了。这部分是用来存储JVM工作的相关数据的,比如Load下来的class定义、静态变量、用于调度的方法和线程栈。

为什么要分为这两个区域呢?其实也是为了垃圾回收器用的,堆内存用来存储Java对象实例,因此这部分才需要进行回收。而非堆内存是JVM自己的工作空间,属于JVM实现的一部分,JVM在实现的时候已经自己实现了内存回收。

值得注意的是,在GC日志中,你会发现PSPermGen也在其中:

[GC-- [PSYoungGen: 569856K->569856K(617472K)] 773089K->928306K(976896K), 0.3285123 secs] [Times: user=0.66 sys=0.08, real=0.33secs]

[Full GC [PSYoungGen: 569856K->0K(617472K)] [ParOldGen: 358450K->359349K(499712K)] 928306K->359349K(1117184K) [PSPermGen: 64652K->64650K(131072K)], 1.4693823 secs] [Times: user=4.09 sys=0.02, real=1.47secs]

[Full GC [PSYoungGen: 569856K->0K(617472K)] [ParOldGen: 359349K->488638K(672768K)] 929205K->488638K(1290240K) [PSPermGen: 65041K->65041K(131072K)], 2.4092196 secs] [Times: user=6.75 sys=0.11, real=2.41 secs]

意思是No-Heap(永久代)也需要垃圾回收?

确实是这样的,因为在永久代中还存储着ClassLoader、Class的元信息(Metadata)、指向Heap区域对象的指针以及字符串池(Internal String)。这些数据其实也需要垃圾回收。

这样看来,把内存区域划分为年轻代(Young Gen)、老年代(Old Gen)和永久代(Permanent Gen)其实是有道理的,虽然老年代的数据不会提升到永久代中。但是这三个区域的数据都是需要垃圾回收的。

Heap(堆内存)

堆内存是垃圾回收器工作的地方,堆内存又分为Eden和两个大小一样的Survivor区,即From和To。

最开始的对象都会存储在Eden中(如果有些大对象无法存入到年轻代,则会直接存入老年代),然后经过Minor GC之后会被提升到Survivor区,然后再提升到老年代。

Stack(栈内存)

Thread Stack 用来存放栈信息,每个线程栈信息里各自有自己的方法栈(包括本地方法栈),在方法栈的每一帧里存储着方法调用的相关信息,比如参数值、局部变量、返回值等。

Program Counter:记录着当前语句执行到哪儿了。

下图中,其实Stack可以归并到No-Heap中。

垃圾回关注的指标

吞吐量

定义:用户代码执行时间  / ( 用户代码执行时间 + 垃圾回收时间)

越高越好,越高表示执行垃圾回收时间越少。

暂停时间

回收时可能需要暂停用户线程,暂停时间越短越好。

执行频率

单位时间垃圾回收执行的次数。

堆内存大小

比如G1回收器就要去比较大的Heap内存。

敏感度(Promptness)

对象变成垃圾到被回收的时间,时间越短表示回收器越敏感。

垃圾回收类型

串行搜集器(Serial)

年轻代(Young Gen)回收

老年代(Old Gen)回收

来年代的回收很简单,步骤是“标记-清除-压缩”:

串行回收器的使用场景

一般引用于不要求“低暂停”的client模式。这里参考server和client的区别。j2se5的client模式下默认使用串行回收器进行垃圾回收。

使用串行回收器的参数:-XX:+UseSerialGC

并行回收器(Paraller)

并行回收器可以利用多个CPU进行并行的垃圾回收。(在多个CPU场景下,使用Serial回收器时,其实只有一个CPU在工作,其他CPU相当于闲置状态)

并行回收器在年轻地啊和老年代进行垃圾回收的操作是一样的,都是标记、转移、压缩,只是它启用了多个CPU并发执行。串行和并行都需要stop-the-world。

并行回收器的使用场景

应用于多CPU场景下,但是没有太大的暂停时间要求,因为还是有可能会发生长时间的老年代垃圾回收。

适用于批处理、账单、财务、科学计算等场景。

j2se5的server模式下默认使用该回收器。

使用并行回收器的参数:-XX:+UseParallelGC

ParNew

这是一个加强版的Parallel回收器。它可以与下面提到的CMS回收器进行配合。

并行压缩回收器(Parallel Compacting)

年轻代使用并行回收器一样的算法(多CPU并行回收)。(stop-the-world)

-XX:+UseParallelOldGC.

对于老年代,回收过程分为三个阶段

并行标记(Marking)

标记出每个区域的活动数据。标记动作其实是和用户线程一起跑的。

计算总结(Summary)

计算各个区域的稠密程度,得出移动数据的方案。(稀疏的往稠密位置移动,压缩速度肯定比相反方向要快)

压缩(Compaction)

把数据移动到一端,保证另外一端空白。

并行压缩回收器的使用场景

多CPU,它相对于并行回收器感觉没有什么区别(谁知道吗???),因为在官方文档中是这样说的:

使用该回收器的参数:-XX:-UseParallelOldGC

并发标记清理回收器(Concurrent Mark-Sweep (CMS))

低延迟的回收器。

一般而言,年轻代的回收不会有太大的暂停。而老年代的回收不会经常执行,所以老年代的回收暂停时间长一点儿也没事。CMS的回收步骤如下:

年轻代还是使用并发回收器(Parallel)。

对于老年代:

初始标记(init mark):单线程stop-the-world执行,短暂停,确定出直接和程序关联的活动对象集合。

并发标记(concurrent marking):根据上一步标记出来的集合,并发找出与集合中元素关联的其他活动对象。这一步的执行是和用户线程并发执行的。

重新标记(remark):由于用户线程也在运行,所以上一步标记出来的对象还有可能又参数了垃圾,所以这里再次stop-the-world,重新找出活动数据。这一步对现场并发执行。很容易理解,这里的stop-the-world也是非常短的。

清理(sweep):根据上一步标记结果,清理内存。

从CMS的执行步骤可以看出,它的核心思想其实就是把事情分成多个步骤来做,不要一次把事情做完,且尽量和用户线程一起执行,从而实现对用户线程的低延迟。

CMS回收器使用场景

任何需要低延迟的应用。甚至在单CPU上都运行良好。

使用CMS回收器参数:-XX:+UseConcMarkSweepGC

G1(Gargage First)回收器

G1回收器是用于server模式下,多处理器、大内存的环境。其目标是高吞吐量、高可用性。在JDK7 update4以后的版本中都支持。长期计划中G1是用来代替CMS回收器的。

G1不像其他回收器那样,把内存明确地划分为三个固定大小的区域。而是把heap看成一个整体。

更多细节详见参考连接。

垃圾收集器参数总结

收集器设置:

-XX:+UseSerialGC:年轻串行(Serial),老年串行(Serial Old)

-XX:+UseParNewGC:年轻并行(ParNew),老年串行(Serial Old)

-XX:+UseConcMarkSweepGC:年轻并行(ParNew),老年串行(CMS),备份(Serial Old)

-XX:+UseParallelGC:年轻并行吞吐(Parallel Scavenge),老年串行(Serial Old)

-XX:+UseParalledlOldGC:年轻并行吞吐(Parallel Scavenge),老年并行吞吐(Parallel Old)

收集器参数:

-XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。

-XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间

-XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)

-XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。

-XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。

参考:

java 内存回收参数_JVM内存模型及垃圾回收的研究总结相关推荐

  1. JVM运行参数_JVM内存模型_常用内存分析工具

    JVM运行参数 常见标准参数 -showversion: 显示当前JVM版本等信息 -D设置系统属性参数: /*** 测试* @author regotto*/ public class JvmTes ...

  2. java 内存调优_JVM内存模型以及性能调优

    JVM 内存模型 JVM.png 程序计数器 程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器.分支.循环.跳转.异常处理.线程恢复等基础功能都需要依赖这个计数器来完成. ...

  3. JVM内存模型与垃圾回收GC

    Java开发有个很基础的问题,虽然我们平时接触的不多,但是了解它却成为Java开发的必备基础--这就是JVM.在C++中我们需要手动申请内存然后释放内存,否则就会出现对象已经不再使用内存却仍被占用的情 ...

  4. 程序猿的日常——JVM内存模型与垃圾回收

    Java开发有个很基础的问题,虽然我们平时接触的不多,但是了解它却成为Java开发的必备基础--这就是JVM.在C++中我们需要手动申请内存然后释放内存,否则就会出现对象已经不再使用内存却仍被占用的情 ...

  5. JVM实用参数(五)新生代垃圾回收

    原文链接  作者: PATRICK PESCHLOW :译者:严亮 本部分,我们将关注堆(heap) 中一个主要区域,新生代(young generation).首先我们会讨论为什么调整新生代的参数会 ...

  6. java垃圾回收 分代_Java-垃圾回收机制-通用的分代垃圾回收机制

    分代垃圾回收机制是基于这样一个事实:不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的回收算法,以便提高回收效率.Java虚拟机将对象分为三种状态:年轻代.年老代.持久代.JVM将 ...

  7. jvm学习第十、十一天、十二天—垃圾回收器1、垃圾回收的相关概述2、 垃圾回收相关算法3、 垃圾回收器

    标题:jvm学习第十.十一天.十二天-垃圾回收器 学习内容: 1.垃圾回收的相关概述 2. 垃圾回收相关算法 3. 垃圾回收器 内容详情: 1.垃圾回收的相关概述 什么是垃圾( Garbage)? 垃 ...

  8. 解读.net垃圾回收和CLR 4.0对垃圾回收所做的改进之一-.Net编程教程

    解读.net垃圾回收和CLR 4.0对垃圾回收所做的改进之一-.Net编程教程 来源:模板无忧 作者:编辑整理更新时间:2009-07-19点击:114 A survey of garbage col ...

  9. java 内存回收参数_JVM常用参数(内存分配 内存回收日志)(七)

    内存监控 -verbose:gc 测试代码 public static voidmain(String[] args){ List classes=new ArrayList();int count= ...

  10. Java基础 —— JVM内存模型与垃圾回收

    目录 一.概述 二.运行时数据区 方法区 运行时常量池 堆 栈 本地方法栈 程序计数器 三.对象访问 四.垃圾回收 如何定义垃圾 1.引用计数法 2.可达性分析 垃圾回收方法 1.Mark-Sweep ...

最新文章

  1. Linux权限管理(suid euid)
  2. UITableView中selectRowAtIndexPath: animated:scrollPosition滚动到指定Row
  3. hdu 5592 ZYB's Premutation (线段树+二分查找)
  4. 注意力机制 神经网络_图注意力网络(GAT)
  5. k3 cloud 文件服务器搭建,k3cloud服务器推荐配置
  6. ASP.NET Core 设置允许跨域访问
  7. Unable to establish loopback connection异常解决
  8. javascript 200列(3)
  9. @property 参数问题
  10. CentOS 5.5 安装VirtualBox
  11. 拓端tecdat|R语言用普通最小二乘OLS,广义相加模型GAM ,样条函数进行逻辑回归LOGISTIC分类
  12. oracle中常用的方法,oracle常用方法
  13. 机器学习基础知识(一):机器学习三大流派
  14. 数据库系统及应用——班级管理系统
  15. c语言读取sgy格式文件,用C语言读写SGY格式的地震数据文件
  16. .Net Core 使用Swagger,且使用自定义UI(Knife4jUI)
  17. c语言表示星期的英语单词周一到周日,sql 获取本周周一和周日
  18. php小卖铺源码,PHP自动化售货发卡网源码-小酒资源
  19. 设计模式与软件体系结构复习资料——设计模式
  20. ddr4 lpddr4区别_笔记本内存LPDDR3就一定不如DDR4吗?宏旺半导体解释两者的区别?...

热门文章

  1. qt自定义控件-柱状刻度尺
  2. 进口十大旋转编码器厂商
  3. Git详解之一 Git起步
  4. 自然语言处理(NLP):国内会议
  5. greedy算法策略高效求解分数背包问题
  6. PHP获取以毫秒级为单位获取当前时间
  7. 诺贝尔奖得主纳什夫妇因车祸去世
  8. 服务器winsxs文件夹怎么清理工具,win10系统winsxs文件夹清理的操作方法
  9. VSS的口令破解算法的思路
  10. Windows主机加固