2024年最新【jvm系列-04】醒目运行时数据区共享区域---堆_java 数据共享区 ...

打印 上一主题 下一主题

主题 495|帖子 495|积分 1485




既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提拔的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比力多,这里只是将部门目录截图出来,全套包罗大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
必要这份系统化资料的朋侪,可以戳这里获取
一,深入理解运行时数据区堆

1,堆空间概念

heap 堆属于是运行时数据区的一块空间,属于一块比力重要的一部门,并且该区域的数据属于线程共享。

⚽ 一个JVM实例只存在一个堆,堆也是java内存管理的核心区域
⚽ Java堆在启动的时候被创建,其空间巨细也被确定,并且是JVM管理的最大的一块内存空间(可调治)
⚽ 堆可以处于物理上不连续的内存空间中,但是在逻辑上他应该是被视为连续的
⚽ 所有的线程共享JVM堆,在这里还可以划分为私有的缓冲区(Thread Local Allocation Buffer)
⚽ 在java虚拟机规范中,所有的对象实例以及数组都应该分配在堆上
⚽ 数组和对象可能永久不会存储在栈上,由于栈帧中保存引用,这个引用指向对象大概数组在堆中的位置
⚽ 在方法竣事之后,堆中的对象不会被立马移除,仅仅在垃圾收集的时候才会被移除
⚽ 堆是GC(Garbage Collection,垃圾接纳器)实行垃圾接纳的重点区域
2,堆内存空间

2.1,堆内存的细分

在JDK8之前,堆内存的逻辑重要分为:新生代+老年代+永久代
在JDK8以及JDK8之后,堆内存重要分为:新生代+老年代+元空间
jdk8的垃圾接纳器如下,可以直接在jdk安装目录下,找到bin目录,然后打开这个 jvisaulvm.exe 文件,然后工具的在插件中安装一个 Visaul GC,就可以看到下面的界面,可知在jdk8中重要是分为Eden区,old区和Metaspace这三个区域,分别对应着新生代,老年代和元空间

也可以直接新建一个application运行并设置其对应jvm的参数,如设置初始巨细和最大巨细为10m,并在控制台上将这个堆信息打印出来
  1. -Xms10m -Xmx10m -XX:+PrintGCDetails
复制代码

在运行项目后,可以发现,PSYoungGen新生代,ParOldGen老年代,Metaspace元空间,其老年代所分配的内存最大。
  1. hello
  2. Heap
  3. PSYoungGen total 2560 K, used 1086 K[0x00000000ffd00000, 0x0000000100000000, 0x0000000100000000)
  4. eden space 2048 K, 28 % used[0x00000000ffd00000, 0x00000000ffd91b68, 0x00000000fff00000)
  5. from space 512 K, 98 % used[0x00000000fff00000, 0x00000000fff7e030, 0x00000000fff80000)
  6. to space 512 K, 0 % used[0x00000000fff80000, 0x00000000fff80000, 0x0000000100000000)
  7. ParOldGen total 7168 K, used 371 K[0x00000000ff600000, 0x00000000ffd00000, 0x00000000ffd00000)
  8. object space 7168 K, 5 % used[0x00000000ff600000, 0x00000000ff65cf38, 0x00000000ffd00000)
  9. Metaspace used 3520 K, capacity 4498 K, committed 4864 K, reserved 1056768 K
  10. class space used 388 K, capacity 390 K, committed 512 K, reserved 1048576 K
复制代码
2.2,堆巨细的根本设置

Java堆区重要用于存储Java对象的实例,那么堆的巨细在JVM启动的时候就已经设定好了,可以直接通过 -Xmx和 -Xms来设定堆的初始内存和最大内存,当堆的最大内存凌驾设置的 -Xms 最大内存时,则会直接抛出内存溢出非常。
  1. -Xms : 设置堆空间(新生代+老年代)的初始内存大小  
  2.            -X表示的是Jvm的运行参数
  3. ​           ms表示的是memory start
  4. -Xmx:设置堆空间(新生代+老年代)的最大内存大小
复制代码
并且在默认的堆空间中,其最大内存为物理电脑内存 / 4,初始内存为物理电脑内存 / 64
在现实开发中,更加建议将初始堆内存和最大的堆内存设置成相同的值,重要是省去堆空间频繁的扩容和开释带来的压力,从而增长这种资源的使用率。
2.3,堆巨细的计算规则

堆巨细重要分为新生代区和老年代区,新生代又分为eden区survive存活区,survive区有分为survive0和survive1区,对象只能存在期中的一个区域里面,每Minitor GC一次,就会从一个survive区到另外一个survive区,如果没有被清算掉,那么他的年事就会+1,当年事到达15时,就会重新生代中加入到老年代里面。
接下来在虚拟机中设置一个600m的堆巨细,依旧是用刚刚那个程序
  1. -Xms600m -Xmx600m
复制代码
然后在main方法中运行之后,输入以下命令
  1. jps : 查看进程号
  2. jstat -gc 进程号
复制代码

可以发现新生代有S0和S1的survive区和Eden区,老年代有old区。对应的容量分别是最大容量和已使用容量,如S0C表示的是survive0区的最大容量,S0U则表示的是survice0已使用的容量。后面也有对应的YGC和FGC发生的次数。
并且在计算总容量的时候,由于数据只能存在一个survive中,因此只计算一个survice的内存巨细,所以偶然计算出来的内容是小于现实设置的内容,但结果是对的,只是jvm在统计时只统计了一个survice存活区的巨细。
3,堆对象

3.1,堆空间对象组成

在JVM中,java对象可以分为两类
   一类是生命周期较短的瞬时对象,这类对象的创建和消亡都比力快
  另一类周期长,某些极端情况下可以和JVM历程的生命周期保持一致
  java堆细分可以分为新生代(YoungGen)和老年代(OldGen),年轻代又可以细分为Eden区和Survivor0空间和Survivor1空间,偶然也被称为(from区和to区)

在这些对象中,也会对新生代和老年代的空间巨细设置对应的比例,新生代和老年代的比例默认为1:2

当然也可以通过命令举行修改这个默认的比例,一般不会修改这个默认值,除非是知道这个老年代的对象偏多
  1. -XX:NewRatio=2 : 表示新生代占1,老年代占2,新生代占1/3,默认比例
  2. -XX:NewRatio=4 : 表示新生代占1,老年代占4,新生代占1/5
复制代码
也可以直接通过命令查看,通过jps查出历程号之后,通过Jinfo去查看
  1. jps
  2. jinfo -flag NewRatio process(进程号)
复制代码
除了老年代和新生代的对空间有比例之外,这个新生代中的Eden区和Survicor区也有对应的比例。如果是在Linux系统下,其比例为8:1 ;如果是在Windows系统下,其比例为6:1
  1. -XX:SurvivorRatio=8 : 表示eden区占8,Survicor区占1
  2. -XX:SurvivorRatio=6 : 表示eden区占6,Survicor区占1
  3. -XX:SurvivorRatio=4 : 表示eden区占4,Survicor区占1
复制代码
这个比例也可以直接通过命令查看,通过jps查出历程号之后,通过Jinfo去查看
  1. jps
  2. jinfo -flag SurvivorRatio process(进程号)
复制代码
因此可以得到一下结论

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

梦见你的名字

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表