JVM运行时数据区-堆

目录

一、堆的核心概述

(一)概述

(二)堆空间细分

(三)jvisualvm工具

二、设置堆内存的大小与OOM

三、年轻代与老年代

四、图解对象分配一般过程

五、对象分配特殊过程

六、常用调优工具

七、MinorGC,MajorGC,FullGC

(一)MinorGC的触发条件

(二)老年代GC(MajorGC/FullGC)触发条件

(三)FullGC的触发条件

八、内存分配策略

九、为对象分配内存TLAB

十、小结堆空间的参数设置

十一、堆是分配对象的唯一选择吗

逃逸分析

1、栈上分配

2、同步策略

3、分离对象或标量替换


这次学习的是JVM运行时数据区中的堆内存

一、堆的核心概述

(一)概述

1、一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域

2、Java堆区在JVM启动的时候即被创建,其空间大小也就确认了。堆内存的大小是可调节的(可以通过参数调节堆的最大内存和初始内存等)

3、Java虚拟机规范规定,堆可以处于物理上不连续的内存空间中,但在逻辑上它应该被视为连续的(这里涉及虚拟内存的概念)。

4、所有的线程共享Java堆,在这里还可以划分线程私有的缓冲区(TLAB)

5、“几乎”所有的对象实例都在堆上分配内存(为什么是“几乎”,后面会讲到逃逸分析)

6、数组和对象可能永远不会存储在栈上,因为栈帧中保存引用,引用指向对象或者数组在堆中的位置(为什么是“可能”,逃逸分析可能直接在栈上为对象分配空间,而不用在堆上开辟空间了)

7、方法结束后,堆中的对象不会马上被移除,仅仅在垃圾收集的时候才会被移除。堆是GC执行垃圾回收的重点区域

(二)堆空间细分

Java7及之前内存逻辑上分为:

  • 新生区
    • Eden区
    • Survivor区
      • from
      • to
        • 谁空谁是to
  • 养老区
  • 永久区

Java8及之后内存逻辑上分为:

  • 新生区
    • Eden区
    • Survivor区
      • from
      • to
        • 谁空谁是to
  • 养老区
  • 元空间

不同书籍叫法不一样,看到这些名词知道是同个意思就可以了

  • 新生区==新生代==年轻代
  • 养老区==老年区==老年代
  • 永久区==永久代

(三)jvisualvm工具

可以通过cmd命令行jvisualvm开启,然后在菜单栏工具中安装插件后可以查看GC情况

二、设置堆内存的大小与OOM

1、-XX:+PrintGCDetails:可开启打印查看方法区实现

2、-Xms :小秘书表示堆空间的起始内存。

3、-Xmx:小明星表示堆空间的最大内存        超过最大内存将抛出OOM

通常将-Xms和-Xmx两个参数配置相同的值,其目的是为了能够在java垃圾会后清理完堆区后,不需要重新分隔计算堆区的大小,从而提高性能

默认情况下,初始内存大小为物理电脑内存大小/64。最大内存大小为物理电脑内存/4

4、cmd命令

jps命令         查看当前程序运行的进程

jstat        查看JVM在gc时的统计信息        jstat -gc 进程号

三、年轻代与老年代

Java对象划分为两类:生命周期短和长的。

新生代与老年代空间默认比例1:2,可以通过设置参数来控制

  • -XX:NewRatio=2,表示新生代占1,老年代占2,新生代占整个堆的1/3
    • ratio:比率比例的意思

jinfo -flag 关键词 进程号,查看参数设定值

  • 在HotSpot中,Eden空间和另外两个Survivor空间缺省所占的比例是:8:1:1
    • -XX:SurvivorRatio调整这个空间比例
  • Eden与Survivor区的比例
    • 实际是6:1:1,因为有自适应机制
      • -XX:-UseAdaptiveSizePolicy:-表示关闭自适应,实际没有用。直接用Ratio分配即可

几乎所有的Java对象都是在Eden区被new出来的。

Eden放不了的大对象,直接进入老年代了。

IBM研究表明,新生代80%的对象都是朝生夕死

-Xmn:洗面奶,设置新生代最大内存大小,如果同时设置了新生代比例与此参数冲突,则以此参数为准。

hotspot为什么要分为新生代和老年代?

因为分代的唯一理由就是优化GC的性能。大多数的对象都是朝生夕死,如果没有进行分代,那所有的对象都在一块,GC的时候要找到哪些对象可以回收就需要对所有对象都进行扫描,性能开销较大。而如果分代的话,新创建的对象放到某一地方,当GC的时候先把这块存储“朝生夕死”对象的区域进行回收,这样就能够以较高的效率释放空间。

设置比例不同可能导致的结果

1)新生代设置过小

    一是新生代GC次数非常频繁,增大系统消耗;二是导致大对象直接进入旧生代,占据了旧生代剩余空间,诱发Full GC

2)新生代设置过大

    一是新生代设置过大会导致老年代过小(堆总量一定),从而诱发Full GC;二是新生代GC耗时大幅度增加

    一般说来新生代占整个堆1/3比较合适

3)Survivor设置过小

    导致对象从eden直接到达旧生代,降低了在新生代的存活时间

4)Survivor设置过大

    导致eden过小,增加了GC频率

    另外,通过-XX:MaxTenuringThreshold=n来控制新生代存活时间,尽量让对象在新生代被回收

四、图解对象分配一般过程

1、new的对象先放在Eden区,此区有大小限制

2、当创建新对象,Eden空间填满时,会触发Minor GC,将Eden不再被其他对象引用的对象进行销毁。再加载新的对象放到Eden区

3、将Eden中剩余的对象移到幸存者0区

4、再次触发垃圾回收,此时上次幸存者下来的,放在幸存者0区的,如果没有回收,就会放到幸存者1区

5、再次经历垃圾回收,又会将幸存者重新放回幸存者0区,依次类推

6、可以设置一个次数,默认是15次,超过15次,则会将幸存者区幸存下来的转去老年区

-XX:MaxTenuringThreshold=N进行设置

总结:

针对幸存者s0,s1区的总结:复制之后有交换,谁空谁是to

频繁在新生区收集,很少在养老区收集,几乎不在永久区/元空间搜集

五、对象分配特殊过程

触发YGC,幸存者区就会进行回收,不会主动进行回收

超大对象eden放不下,就要看Old区大小是否可以放下。如果Old区放得下,就直接放到Old区。如果也放不下,需要FullGC(MajorGC),这两GC概念还是有区别的。下面详解

六、常用调优工具

  1. JDK命令行
  2. Eclipse:Memory Analyzer Tool
  3. Jconsole
  4. VisualVM
  5. Jprofiler
  6. Java Flight Recorder

七、MinorGC,MajorGC,FullGC

针对 HotSpot VM 的实现,它里面的 GC 其实准确分类只有两大种:

部分收集 (Partial GC):

  • 新生代收集(Minor GC / Young GC):只对新生代进行垃圾收集;
  • 老年代收集(Major GC / Old GC):只对老年代进行垃圾收集。需要注意的是 Major GC 在有的语境中也用于指代整堆收集;
  • 混合收集(Mixed GC):对整个新生代和部分老年代进行垃圾收集。

整堆收集 (Full GC):收集整个 Java 堆和方法区。

(一)MinorGC的触发条件

当年轻代空间不足时,就会触发MinorGC,这里的年轻代指的是Eden满,Survivor满不会触发GC。每次MinorGC会清理年轻代的内存

因为Java对象大多朝生夕灭,所以MinorGC非常频繁。MinorGC会引发STW(stop the world即停止用户线程,让GC线程运行)

(二)老年代GC(MajorGC/FullGC)触发条件

指发生在老年代的GC,对象从老年代消失,我们说“MajorGC”“FullGC”发生了

出现了MajorGC,经常会伴随至少一次MinorGC

但是并非绝对,在Parallel Scavenge收集器的收集策略里就直接进行MajorGC的策略选择过程,也就是老年代空间不足,会先尝试触发MinorGC,如果之后空间还不足,则触发MajorGC

MajorGC的速度比MinorGC慢10倍以上,STW的时间更长

如果MajorGC后,内存还不足,就报OOM了

(三)FullGC的触发条件

1、调用System.gc()时,系统建议执行FullGC,但是不必然执行

2、老年代空间不足

3、方法区空间不足

4、通过MinorGC后进入老年代的平均大小,大于老年代的可用内存

5、由Eden区,Survivor 0区向Survivor 1区复制时,对象的大小大于ToSpace可用内存,则把改对象转存到老年代,且老年代的可用内存小于该对象的大小

FullGC是开发或调优中尽量要避免的,这样暂停时间会短一些。

八、内存分配策略

1、如果对象再Eden出生并经过第一次MinorGC后仍然存活,并且能被Survivor区容纳,则被移动到Survivor空间中,并将对象年龄设置为1,对象再Survivor区每熬过一次MinorGC,年龄就+1,当年龄增加到一定程度(默认为15,不同Jvm,GC都所有不同)时,就会被晋升到老年代中

可以通过参数 -XX:MaxTenuringThreshold 设置阈值

2、如果大对象Eden放不下,会直接分配到老年代

我们应尽量避免程序中出现过多的大对象

3、动态对象年龄分配

如果Survivor区中相同年龄的所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代,无需等到MaxTenuringThreshold中要求的年龄

4、空间分配担保机制

  • 在发生Minor GC之前,虚拟机会检查老年代最大可用的连续空间,是否大于新生代所有对象的总空间
    • 如果大于,则此次MinorGC是安全的
    • 如果小于,则查看-XX:HandlePromotionFailure设置是否允许担保失败
      • true
        • 会继续检查老年代最大可用连续空间是否大于历次晋升到老年代的对象的平均大小
        • 大于,则尝试进行一次MinorGC,但是这次MinorGC依然是有风险的
        • 小于,则改为进行一次FullGC
      • false
        • 则改为进行一次FullGC
  • jdk6update24之后,这个参数不会再影响到虚拟机的空间分配担保策略。规则改为只要老年代的连续空间大于新生代对象总大小,或者历次晋升的平均大小,就会进行MinorGC;否则进行FullGC

通过 -XX:HandlePromotionFailure=true/false 进行设置是否允许担保失败 

九、为对象分配内存TLAB

堆区是线程共享区域,任何线程都可以访问到堆区的共享数据。由于对象实例的创建在JVM中非常频繁,因此在并发环境下从堆区中划分内存空间是线程不安全的。为避免多个线程操作同一地址,需要使用加锁等机制,进而影响分配速度。

于是TLAB(Thread Local Allocation Buffer)出现了

从内存模型而不是垃圾收集的角度,对Eden区域进行划分,JVM为每个线程分配了一个私有缓存区域,包含在Eden空间中

多线程同时分配内存时,使用TLAB可以避免一系列的非线程安全问题,同时还能够提升内存分配的吞吐量,因此我们将这种内存分配方式称为快速分配策略

1、尽管不是所有的对象实例都能够在TLAB中成功分配内存,但是JVM确实是将TLAB作为内存分配的首选

2、开发人员通过-XX:UseTLAB设置是否开启TLAB空间

3、默认情况下,TLAB空间内存非常小,仅占有整个Eden空间的1%,通过-XX:TLABWasteTargetPercent设置TLAB空间所占用Eden空间的百分比大小

4、一旦对象在TLAB空间分配内存失败,JVM就会尝试通过使用加锁机制确保数据操作的原子性,从而直接在Eden空间中分配内存

十、小结堆空间的参数设置

十一、堆是分配对象的唯一选择吗

随着JIT编译器的发展与逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术,将会导致一些微秒变化,所有对象分配到堆上渐渐变得不那么绝对了。

有一种特殊情况,如果经过逃逸分析后发现,一个对象并没有逃逸出方法的话,那么就可能被优化成栈上分配,这样无需堆上分配,也不需要垃圾回收了,也是最常见的堆外存储技术

逃逸分析

逃逸分析的基本行为就是分析对象动态作用域

  • 当一个对象在方法中定义后,对象只在方法内部使用,则认为没有发生逃逸
  • 当一个对象在方法中被定义后,它被外部方法引用,则认为发生逃逸,例如作为调用参数传递到其他地方中

1、栈上分配

如果未发生逃逸,将堆分配转为栈分配,如果一个对象在子程序中被分配,要使指向该对象的指针永远不会逃逸,对象可能是栈分配的候选,而不是堆分配

2、同步策略

如果一个对象被发现只能从一个线程被访问到,对于这个对象的操作可以不考虑同步

JIT编译器可以借助逃逸分析来判断同步块所使用的的锁对象,是否只能够被一个线程访问,而没有被发布到其他线程。如果没有,那么JIT编译器在编译这个同步块的时候,就会取消对这部分代码的同步。这样就大大提高并发性和性能,这个取消同步的过程就叫同步省略,也叫锁消除

3、分离对象或标量替换

有的对象可能不需要作为一个连续的内存结构存在,也可以被访问到,那么对象的部分(或全部)可以不存储在内存。而是存储在CPU寄存器中

标量是指一个无法再分解的更小的数据的数据。Java中原始数据类型就是标量

可以分解的数据叫聚合量,Java中的对象就是聚合量,因为他可以分解成其他聚合量和标量

标量替换参数:-XX:EliminateAllocations,默认打开

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/130989.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetCode 416.分割等和子集 + 01背包 + 动态规划 + 记忆化搜索 + 递推 + 空间优化

关于此题我的往期文章: LeetCode 416.分割等和子集(动态规划【0-1背包问题】采用一维数组dp:滚动数组)_呵呵哒( ̄▽ ̄)"的博客-CSDN博客https://heheda.blog.csdn.net/article/details/133212716看本期文章时&…

关于JADX和JEB的小问题

关于JADX和JEB的小问题 很久没水过技术文啦,最近也刚好遇到点小问题,特此记录 第一个问题 在处理app加密逻辑的时候一直拿不到正确的密文,反复看了反编译出来的代码(如下图) public static string n(String str, Stri…

基础课22——云服务(SaaS、Pass、laas、AIaas)

1.云服务概念和类型 云服务是一种基于互联网的计算模式,通过云计算技术将计算、存储、网络等资源以服务的形式提供给用户,用户可以通过网络按需使用这些资源,无需购买、安装和维护硬件设备。云服务具有灵活扩展、按需使用、随时随地访问等优…

linux 查看当前目录下每个文件夹大小

要在 Linux 中查看当前目录下每个文件夹的大小,可以使用 du 命令(磁盘使用情况)结合其他一些选项。下面是几个常用的命令示例: 显示当前目录下每个文件夹的大小——只显示一层文件夹: du -h --max-depth1该命令会以人…

2023年内衣行业分析:京东大数据平台-服饰内衣市场解析

如今,女性消费力的提升正在推动国内女性内衣市场份额逐年提升。而今年,内衣市场更是进入了存量之战,增长趋势明显减弱。 根据鲸参谋数据显示,今年1月至9月,京东平台内衣(文胸)累计销量约500万件…

【数智化案例展】某国际高端酒店品牌——呼叫中心培训数智化转型项目

‍ 维音案例 本项目案例由维音投递并参与数据猿与上海大数据联盟联合推出的《2023中国数智化转型升级创新服务企业》榜单/奖项”评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 培训是呼叫中心管理的重要环节,由于员工流动性强、培训需求多样、考核流程繁琐…

2003 - Can‘t connect to MysQL server on ‘39.108.169.0‘ (10060 “Unknown error“)

问题描述 某天和往常一样启动java项目,发现数据库出问题了,然后打开navicat,发现数据库的链接都连接不上, 一点击就会弹出报错框: 然后就各种上网搜索。 解决方案 上网查了一些解决方案,大部分都是说看…

hivesql,sql 函数总结:

1、NVL函数与Coalesce差异 -- select nvl(null,8); -- 结果是 8 -- select nvl(,7); -- 结果是"" -- select coalesce(null,null,9); -- 结果是 9 -- select coalesce("",null,9); -- 结果是 "" 1.2、 NVL函数与Coalesce差异 …

DB-GPT介绍

DB-GPT介绍 引言DB-GPT项目简介DB-GPT架构关键特性私域问答&数据处理多数据源&可视化自动化微调Multi-Agents&Plugins多模型支持与管理隐私安全支持数据源 子模块DB-GPT-Hub微调参考文献 引言 随着数据量的不断增长和数据分析的需求日益增多,将自然语言…

Technology strategy Pattern 学习笔记4 - Creating the Strategy-Corporate Context

Creating the Strategy-Corporate Context 1 •. Stakeholder Alignment 1.1 要成功,要尽可能获得powerful leader的支持 1.2 也需要获得最高执行层的支持 1.3 Determining(确定) Stakeholders 需要建立360度组织图,确认三类人…

基于深度学习的目标检测算法 计算机竞赛

文章目录 1 简介2 目标检测概念3 目标分类、定位、检测示例4 传统目标检测5 两类目标检测算法5.1 相关研究5.1.1 选择性搜索5.1.2 OverFeat 5.2 基于区域提名的方法5.2.1 R-CNN5.2.2 SPP-net5.2.3 Fast R-CNN 5.3 端到端的方法YOLOSSD 6 人体检测结果7 最后 1 简介 &#x1f5…

适用于 Linux 的 WPF:Avalonia

许多年前,在 WPF 成为“Windows Presentation Foundation”并将 XAML 作为 .NET、Windows 等的 UI 标记语言引入之前,有一个代号为“Avalon”的项目。Avalon 是 WPF 的代号。XAML 现在无处不在,XAML 标准是一个词汇规范。 Avalonia 是一个开…

EtherCAT主站写从站EEPROM抓包分析

0 工具准备 1.EtherCAT主站 2.EtherCAT从站(本文使用步进电机驱动器) 3.Wireshark1 抓包分析 1.1 报文总览 本文主站设置从站1字地址为0的EEPROM数据为0x3C00(设置完毕后请还原字0的EEPROM数据),使用Wireshark抓取到…

Day 6 登录页以及路由(四)Vue页面处理

系列文章目录 本系列记录一下通过Abp搭建后端,VueElement UI Plus搭建前端,实现一个小型项目的过程。 Day 1 Vue 页面框架Day 2 Abp框架下,MySQL数据迁移时,添加表和字段注释Day 3 登录页以及路由 (一)Day 4 登录页及…

CleanMyMac X2024破解版下载地址链接

如果你是一位Mac用户,你可能会遇到一些问题,比如Mac运行缓慢、磁盘空间不足、应用程序难以管理等。这些问题会影响你的Mac的性能和体验,让你感到沮丧和无奈。那么,有没有一款软件可以帮助你解决这些问题呢?答案是肯定的…

(免费领源码)Java#Springboot#mysql高校实训管理平台01557-计算机毕业设计项目选题推荐

目 录 摘要 1 绪论 1.1 研究背景 1.2 研究意义 1.3论文结构与章节安排 2 高校实训管理平台系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系…

「图像 cv2.seamlessClone」无中生有制造数据

上一篇博客【「图像 merge」无中生有制造数据 】写的是图片直接融合,此方法生成的图片相对而言比较生硬,虽然目标图片已经透明化处理过了,但是生成的图片依旧很假 除了上述上述的图片叠加融合之外,还有一种更加自然的融合方法&…

Nginx+keepalived实现七层的负载均衡

1.keepalived VRRP 介绍 keepalived是什么? keepalived是集群管理中保证集群高可用的一个服务软件,用来防止单点故障。 keepalived工作原理 keepalived是以VRRP协议为实现基础的,VRRP全称Virtual Router Redundancy Protocol&…

C#使用Oracle.ManagedDataAccess.dll

1、添加引用 在网上下载一个Oracle.ManagedDataAccess.dll&#xff0c;引用即可&#xff0c;操作不受操作系统的位数限制&#xff0c;服务器也不Oracle客户端&#xff1b; 2、web.config字串 <appSettings> <add key"hrp" value"Data Source (DES…

ElasticSearch基本使用

概述 安装 关于ES的安装不做重点讲解&#xff0c;这里提供一个k8s基于sts创建以及ingress访问的模板文件。 --- apiVersion: apps/v1 kind: StatefulSet metadata:labels:app: elasticsearchcomponent: masterrelease: elasticsearchname: elasticsearch-masternamespace: es s…