文档章节

JVM内存模型及垃圾回收算法

Corlang
 Corlang
发布于 2016/05/31 21:40
字数 1617
阅读 206
收藏 8

JVM内存模型总体架构图

JVM内存模型总体架构图

程序计数器

多线程时,当线程数超过CPU数量或CPU内核数量,线程之间就要根据时间片轮询抢夺CPU时间资源。因此每个线程有要有一个独立的程序计数器,记录下一条要运行的指令。线程私有的内存区域。如果执行的是JAVA方法,计数器记录正在执行的java字节码地址,如果执行的是native方法,则计数器为空。

虚拟机栈

线程私有的,与线程在同一时间创建。管理JAVA方法执行的内存模型。每个方法执行时都会创建一个桢栈来存储方法的的变量表、操作数栈、动态链接方法、返回值、返回地址等信息。栈的大小决定了方法调用的可达深度(递归多少层次,或嵌套调用多少层其他方法,-Xss参数可以设置虚拟机栈大小)。栈的大小可以是固定的,或者是动态扩展的。如果请求的栈深度大于最大可用深度,则抛出stackOverflowError;如果栈是可动态扩展的,但没有内存空间支持扩展,则抛出OutofMemoryError。 使用jclasslib工具可以查看class类文件的结构。下图为栈帧结构图:

栈帧结构图

本地方法区

和虚拟机栈功能相似,但管理的不是JAVA方法,是本地方法,本地方法是用C实现的。

JAVA堆

线程共享的,存放所有对象实例和数组。垃圾回收的主要区域。可以分为新生代和老年代(tenured)。 新生代用于存放刚创建的对象以及年轻的对象,如果对象一直没有被回收,生存得足够长,老年对象就会被移入老年代。 新生代又可进一步细分为eden、survivorSpace0(s0,from space)、survivorSpace1(s1,to space)。刚创建的对象都放入eden,s0和s1都至少经过一次GC并幸存。如果幸存对象经过一定时间仍存在,则进入老年代(tenured)。

java堆内存

方法区

线程共享的,用于存放被虚拟机加载的类的元数据信息:如常量、静态变量、即时编译器编译后的代码。也成为永久代。如果hotspot虚拟机确定一个类的定义信息不会被使用,也会将其回收。回收的基本条件至少有:所有该类的实例被回收,而且装载该类的ClassLoader被回收

垃圾回收算法

标记-清除算法(Mark-Sweep)

从根节点开始标记所有可达对象,其余没标记的即为垃圾对象,执行清除。但回收后的空间是不连续的。

复制算法(copying)

将内存分成两块,每次只使用其中一块,垃圾回收时,将标记的对象拷贝到另外一块中,然后完全清除原来使用的那块内存。复制后的空间是连续的。复制算法适用于新生代,因为垃圾对象多于存活对象,复制算法更高效。在新生代串行垃圾回收算法中,将eden中标记存活的对象拷贝未使用的s1中,s0中的年轻对象也进入s1,如果s1空间已满,则进入老年代;这样交替使用s0和s1。这种改进的复制算法,既保证了空间的连续性,有避免了大量的内存空间浪费。

复制算法

标记-压缩算法(Mark-compact)

适合用于老年代的算法(存活对象多于垃圾对象)。 标记后不复制,而是将存活对象压缩到内存的一端,然后清理边界外的所有对象。 标记-压缩算法

JVM参数:

-XX:+PrintGCDetails  打印垃圾回收信息
-Xms 为Heap区域的初始值,线上环境需要与-Xmx设置为一致,否则capacity的值会来回飘动
-Xmx 为Heap区域的最大值
-Xss(或-ss) 线程栈大小(指一个线程的native空间)1.5以后是1M的默认大小
-XX:PermSize与-XX:MaxPermSize  方法区(永久代)的初始大小和最大值(但不是本地方法区)
-XX:NewRatio  老年代与新生代比率
-XX:SurvivorRatio  Eden与Survivor的占用比例。例如8表示,一个survivor区占用 1/8 的Eden内存,即1/10的新生代内存,为什么不是1/9?因为我们的新生代有2个survivor,即S1和S22。所以survivor总共是占用新生代内存的 2/10,Eden与新生代的占比则为 8/10。
-XX:MaxHeapFreeRatio  GC后,如果发现空闲堆内存占到整个预估的比例小于这个值,则减小堆空间。
-XX:MinHeapFreeRatio  GC后,如果发现空闲堆内存占到整个预估的比例大于这个值,则增大堆空间。
-XX:NewSize    新生代大小

JVM优化策略

  • 1、由于fullGC比minorGC的成本高很多,因此尽量将new的对象放在新生代中。策略是将新生代空间调大,因为新生代太小,则系统会将对象放到老年代。
  • 2、大对象进入老年代。因为如果大对象占用了新生代空间,则会导致系统将大量小的新生代对象放入到老年代中,这对GC来说很不利。因此尽量避免使用短命的大对象。-XX:PretenureSizeThreshold设置对象进入老年代的阀值,对象大小超过这个值就直接进入老年代。
  • 3、设置对象进入老年代的年龄。每经历一次GC,对象的年龄就+1,-XX:MaxTenuringThreshold设置进入老年代的最大年龄。
  • 4、吞吐量最佳方案:Xmn (新生代大小)一般占整个堆大小(xmx)的一半,-XX:+UseParallelGC新生代用并行回收收集器,-XX:+UseParallelOldGC老年代用并行回收收集器,-XX:ParallelGCThreads:垃圾回收线程数:一般设置为CPU总数(总核数)

参考文章:

本文转载自:http://www.cnblogs.com/AloneSword/p/4262255.html

Corlang
粉丝 6
博文 35
码字总数 6634
作品 0
南京
程序员
私信 提问
《成神之路-基础篇》JVM——垃圾回收(已完结)

Java内存模型,Java内存管理,Java堆和栈,垃圾回收 本文是[《成神之路系列文章》][1]的第一篇,主要是关于JVM的一些介绍。 持续更新中 Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收 ...

2018/05/05
0
0
2019年面试必备:最新Java核心知识点(3)—JAVA多线程并发(上)

核心知识——JVM jvm基本概念: JVM 是可运行 Java 代码的假想计算机 ,包括一套字节码指令集、一组寄存器、一个栈、 一个垃圾回收,堆 和 一个存储方法域JVM 是运行在操作系统之上的,它与硬...

我最喜欢三大框架
06/05
12
0
聊聊JAVA虚拟机中的垃圾收集器

前言 JAVA虚拟机的垃圾收集器是虚拟机内存的清道夫,它的存在让JAVA开发人员能将更多精力投入到业务研发上。了解垃圾收集器,并利用好这个工具,能更好的保障服务稳定性。这篇文章通过分析J...

lilugoodjob
2018/07/02
0
0
Java虚拟机基础——4内存回收机制

Java虚拟机整体篇幅如下: Java虚拟机基础——1Java的内存模型 Java虚拟机基础——2JVM运行时数据区 Java虚拟机基础——3类加载机制 Java虚拟机基础——4内存回收机制 本篇文章的内容如下: ...

隔壁老李头
2018/10/03
0
0
JVM系列第8讲:JVM 垃圾回收机制

在第 6 讲中我们说到 Java 虚拟机的内存结构,提到了这部分的规范其实是由《Java 虚拟机规范》指定的,每个 Java 虚拟机可能都有不同的实现。其实涉及到 Java 虚拟机的内存,就不得不谈到 Ja...

陈树义
2018/11/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

zk中ToBeAppliedRequestProcessor解析

ToBeAppliedRequestProcessor在Leader中 在已处理事务和最后处理事务处理器之间,处理器链上下一个是FinalRequestProcessor public void processRequest(Request request) throws RequestPro...

writeademo
31分钟前
3
0
Allegro快捷键设置-PCB环境

立题简介: 内容:简单介绍Allegro绘制的PCB环境下的快捷键; 来源:实际使用得出; 作用:对Allegro绘制PCB快捷键进行介绍; PCB环境:Cadence 16.6; 立题详解: 对“allegro”板而言,其在...

demyar
32分钟前
2
0
idea maven web项目启动build时报错java.lang.NullPointerException

之前还好好的,重启一下idea就报这个错了,大概率是tomcat没杀掉端口被占用了,在tomcat配置中更换一下sever端口就好了

宇辰OSC
36分钟前
3
0
weed3-2.3.1.查询之输出

Weed3 一个超轻量级ORM框架(只有0.1Mb哦) 源码:https://github.com/noear/weed3 源码:https://gitee.com/noear/weed3 查询可是个复杂的话题了,可能我们80%的数据库处理都在查询。 今天先...

刘之西东
36分钟前
3
0
【Android JetPack系列】数据绑定:DataBinding

参考MVVM

Agnes2017
44分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部