【JVM】jvm虚拟机中的堆
创始人
2024-04-27 23:35:31
0

jvm虚拟机中的堆

  • 一、JVM体系结构
  • 二、Java堆简介
    • 2.1 堆的特点
    • 2.2 堆空间细分
    • 2.3 堆空间的分代思想
    • 2.4 堆的默认大小
  • 三、JVM堆内存常用参数
  • 四、垃圾回收算法(GC,Garbage Collection)
    • 4.1 标记-清除(Mark-Sweep)
    • 4.2 复制(Copy)
    • 4.3 标记-整理(Mark-Compact)
  • 五、常见错误
    • 5.1 为什么会堆内存溢出?

一、JVM体系结构

在这里插入图片描述我们接下来说的JVM中运行时数据区中的堆区(Heap Area)。

二、Java堆简介

对于Java应用程序来说,Java堆(Java Heap)是虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块区域,在虚拟机启动时创建。此内存区域的唯一的目的就是存放对象实例,Java世界里“几乎”所有的对象实例都在这里分配内存。在《Java虚拟机规范》中对Java堆的描述是:“所有的对象实例以及数组都应当在堆上分配”。

2.1 堆的特点

  1. 一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域
  2. Java堆区在JVM启动的时候被创建,其空间大小也就确定了。是JVM管理的最大一块内存空间。但是堆内存的大小是可以调节的
  3. 《Java虚拟机规范》规定,堆可以处于 **物理上不连续** 的内存空间中,但是 **逻辑上** 它应该是被视为 连续的
  4. 堆针对一个 JVM 进程 来说是唯一的,也就是一个进程只有一个JVM,但是进程包含多个线程,他们是共享同一堆空间的
  5. 所有的线程共享Java堆,在这里还可以划分线程私有的缓冲区**Thread Local Allocation Buffer, TLAB**

2.2 堆空间细分

在这里插入图片描述从上图中我们可以知道,堆的空间可以被细分为很多区:

  1. 年轻代(Young Gen)
  2. 老年代(Old Gen)
  3. 永久代(Perm Gen)

其中年轻代被分为 Eden 空间Survivor 1空间From区)、Survivor 0空间To 区),备注:谁空谁就是 To区

  • 所有对象一出生都会在Eden区,并且对象年龄为0。Eden区满了之后会触发minor GC, minor GC只回收年轻代中需要回收的对象。每一次minor GC,若该对象没有被回收,那么对象的年龄就会 + 1。对象到达阈值以后该对象会进入老年代(android阈值为6)。
  • 当老年代空间满了以后会触发full GC,full GC会同时回收年轻代和老年代中所有需要回收的对象。

2.3 堆空间的分代思想

年轻代、老年代、永久代

  • 年轻代用于放置临时对象或者生命周期短的对象
  • 老年代用于放置生命周期长的对象
  • 永久代或者元空间,用于存放常量
  • minor GC (轻GC)只管年轻代,Full GC(重GC) 同时管理年轻代和老年代

为什么要分代?有什么好处?

  • 经研究表明,不同对象的生命周期是不一致的,但是在具体的使用过程中,70%–90%的对象都是临时对象
  • 分代唯一的理由就是优化GC的性能,如果没有分代,那么所有对象都处于一块空间,GC想要回收,则GC需要描述所有的对象,分代之后,长期持有的对象可以被挑出,短期持有的对象可以固定在一个位置回收,省掉很大一部分空间利用。

2.4 堆的默认大小

  • 初始大小:电脑物理内存的 1/64
  • 最大内存大小:电脑物理内存的 1/4

Runtime类:该类对应的JVM运行时数据区

long initialMemory = Runtime.getRuntime().totalMemory();
long maxMemory = Runtime.getRuntime().maxMemory();
long freeMemory = Runtime.getRuntime().freeMemory();

三、JVM堆内存常用参数

参数说明
-Xms堆内存初始大小,单位m(兆)、g(G)
-Xmx(MaxHeapSize)堆内存最大允许大小,一般不要大于物理内存的80%
-XX:PermSize非堆内存初始大小,一般应用设置初始化200m,最大1024m就够了
-XX:MaxPermSize非堆内存最大允许大小
-XX:NewSize(-Xns)年轻代内存初始大小
-XX:MaxNewSize(-Xmn)年轻代内存最大允许大小,也可以缩写
-XX:SurvivorRatio=8年轻代中Eden区与Survivor区的容量比例值,默认为8,即8:1
-Xss堆栈内存大小

四、垃圾回收算法(GC,Garbage Collection)

以下几种垃圾回收算法只是抛砖引玉,具体详细的算法说明还需要自行搜索并加以学习,算法还有很多,所以学习的东西有很多哦。

红色是标记的非活动对象,绿色是活动对象。

4.1 标记-清除(Mark-Sweep)

GC分为两个阶段,标记和清除。首先标记所有可回收的对象,在标记完成后统一回收所有被标记的对象。同时会产生不连续的内存碎片。碎片过多会导致以后程序运行时需要分配较大对象时,无法找到足够的连续内存,而不得已再次触发GC。
在这里插入图片描述

4.2 复制(Copy)

将内存按容量划分为两块,每次只使用其中一块。当这一块内存用完了,就将存活的对象复制到另一块上,然后再把已使用的内存空间一次清理掉。这样使得每次都是对半个内存区回收,也不用考虑内存碎片问题,简单高效。缺点需要两倍的内存空间。
在这里插入图片描述

4.3 标记-整理(Mark-Compact)

也分为两个阶段,首先标记可回收的对象,再将存活的对象都向一端移动,然后清理掉边界以外的内存。此方法避免标记-清除算法的碎片问题,同时也避免了复制算法的空间问题。

一般年轻代中执行GC后,会有少量的对象存活,就会选用复制算法,只要付出少量的存活对象复制成本就可以完成收集。

而老年代中因为对象存活率高,没有额外过多内存空间分配,就需要使用标记-清理或者标记-整理算法来进行回收。
在这里插入图片描述

五、常见错误

5.1 为什么会堆内存溢出?

在年轻代中经过GC后还存活的对象会被复制到老年代中。当老年代空间不足时,JVM会对老年代进行完全的垃圾回收(Full GC)。如果GC后,还是无法存放从Survivor区复制过来的对象,就会出现OOM(Out of Memory)。
OOM(Out Of Memory)异常常见有以下几个原因:

  1. 老年代内存不足:java.lang.OutOfMemoryError:Javaheapspace
  2. 永久代内存不足:java.lang.OutOfMemoryError:PermGenspace
  3. 代码bug,占用内存无法及时回收

OOM在这几个内存区都有可能出现,实际遇到OOM时,能根据异常信息定位到哪个区的内存溢出。

可以通过添加个参数 -XX:+HeapDumpOnOutMemoryError,让虚拟机在出现内存溢出异常时Dump出当前的内存堆转储快照以便事后分析。

熟悉了JAVA内存管理机制及配置参数,下面是对JAVA应用启动选项调优配置:

JAVA_OPTS=“-server -Xms512m -Xmx2g -XX:+UseG1GC -XX:SurvivorRatio=6 -XX:MaxGCPauseMillis=400 -XX:G1ReservePercent=15 -XX:ParallelGCThreads=4 -XX:
ConcGCThreads=1 -XX:InitiatingHeapOccupancyPercent=40 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:…/logs/gc.log”

设置堆内存最小和最大值,最大值参考历史利用率设置

设置GC垃圾收集器为G1

启用GC日志,方便后期分析

完结!

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...