JVM之堆

news/2024/12/22 18:42:04/

堆的基本内容:

Java堆(Java Heap)是虚拟机所管理的内存中最大的一块,Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建,此内存区域的唯一目的就是存放对象实例,Java 世界里“几乎”所有的对象实例都在这里分配内存。

Java堆可以处于物理上不连续的内存空间中,但在逻辑上它应该被视为连续的,这点就像我们用磁盘空间去存储文件一样,并不要求每个文件都连续存放。但对于大对象(例如:数组对象),多数虚拟机实现出于实现简单、存储高效的考虑,很可能会要求连续的内存空间。

注:永久区[元空间]在逻辑上是存在的,而在物理上是不存在的

Heap:

一个JVM只有一个堆内存,堆内存的大小是可以进行调节的

类加载器读取了类文件后,会将类,常量,方法,变量,以及所有引用对象的真实对象.

堆中的区域详解:

堆内存中还要细分三个区域:

新生区[伊甸园区] Young/New
养老区 old
永久区 Perm

在这里插入图片描述在这里插入图片描述

Young/New Generation 新生代:

程序中新建的对象都将分配到新生代中,新生代又由Eden(伊甸园)与两块Survivor(幸存者) Space 构成

Eden 与Survivor Space 的空间大小比例默认为8:1,即当Young/New Generation 区域的空间大小总数为10M 时,Eden 的空间大小为8M,两块Survivor Space 则各分配1M,这个比例可以通过-XX:SurvivorRatio 参数来修改,Young/New Generation的大小则可以通过-Xmn参数来指定。

Eden伊甸园:

刚刚新建的对象将会被放置到Eden 中,这个名称寓意着“对象们可以在其中快乐自由的生活”

Survivor Space:

幸存者区域是新生代与老年代的缓冲区域,两块幸存者区域分别为From Space(S0) 与To Space(S1),当年轻代空间不足时,就会触发Minor GC,这里的年轻代空间不足指的是Eden区满,Survivor区满不会触发GC[每次Minor GC 会清理年轻代的内存],当触发Minor GC 后将仍然存活的对象移动到S0中去,随之Eden 就被清空,可以分配给新的对象

当再一次触发Minor GC后,S0和Eden 中存活的对象被移动到S1中,S0即被清空。在同一时刻, 只有Eden和一个Survivor Space同时被操作所以S0与S1两块Survivor 区同时会至少有一个为空闲的。

当每次对象从Eden 复制到Survivor Space 或者从Survivor Space
之间复制,计数器会自动增加其值。,默认情况下如果复制发生超过16次,JVM
就会停止复制并把他们移到老年代中去,如果一个对象不能在Eden中被创建,它会直接被创建在老年代中。

新生代GC(Minor GC):

指发生在新生代的垃圾收集动作,因为 Java 对象大多都具备朝生夕灭的特性,通常很多的对象都活不过一次GC,所以Minor GC 非常频繁,一般回收速度也比较快。

Java堆是垃圾收集器管理的内存区域,因此,它也被称作“GC堆”(Garbage Collected Heap),GC垃圾回收,主要是在伊甸园和养老区,假设内存满了,OOM,堆内存不够,就会出栈堆溢出现象。

举例:

import java.util.Random;public class person{public static void main(String[]args){String str="hello";while(true){str+=str+new Random().nextInt(888888888)+new Random().nextInt(999999999);}}

报错内容如下:

Exception in thread "main" java.lang.OutOfMemoryError: Overflow: String length out of rangeat java.base/java.lang.StringConcatHelper.checkOverflow(StringConcatHelper.java:57)at java.base/java.lang.StringConcatHelper.mix(StringConcatHelper.java:138)at xxx.person.main(person.java:9)

Java堆既可以被实现成固定大小的,也可以是可扩展的,不过当前主流的Java虚拟机都是按照可扩展来实现的可通过通过参数-Xmx和-Xms设定)。如果在Java堆中没有内存完成实例分配,并且堆也无法再扩展时,Java虚拟机将会抛出OutOfMemoryError异常。

改变当前JVM的堆内存大小的方式:

以idea为例:

在这里插入图片描述

在这里插入图片描述

注:自JDK8以后,永久存储区被称为元空间

永久区:这个区域常驻内存,用来存放JDK自身携带的Class对象。Interface原数据,存储的是java运行时的一些环境或者类信息,这个区域不存在垃圾回收,关闭JVM虚拟就会释放这个区域的内存。

一个启动类,加载了大量的第三方jar包,Tomcat部署了太多的应用,大量生成的反射类,不断地被加载,直到内存满,就会出现OOM

JDK1.6之前:永久代,常量池是在方法区

JDK1.7:永久代,但是慢慢的退化了,去永久代,常量池在堆中

JDK1.8之后:无永久代,常量池在元空间


http://www.ppmy.cn/news/4952.html

相关文章

Mycat(6):mycat简单配置

1 找到conf/schema.xml并备份 2 配置虚拟表table[在schema里面] 其中 sharding-by-intfile 为rule.xml中的规则 规则文件为conf文件夹中的partition-hash-int.txt 3 配置数据节点dataNode 现在数据库新建3个数据库,skywalking,skywalking1,s…

艾美捷利妥昔单抗Rituximab参数及应用

艾美捷利妥昔单抗Rituximab背景: 利妥昔单抗是一种针对CD20抗原的基因工程嵌合鼠/人单克隆IgG1κ抗体。利妥昔单抗的分子量约为145 kD。利妥昔单抗由哺乳动物细胞(中国仓鼠卵巢)产生。 艾美捷利妥昔单抗Rituximab基本参数: 中文…

Jenkins(2)— 配置webhooks触发器

1、项目配置 项目配置 >> 构建触发器 >> 选择Gitee webhook触发器 生成Gitee WebHook密码:46d678257c0399b105635bcb9722ea09 2、Gitee配置 Gitee项目 >> 管理 >> 配置WebHooks 注意: 由于我的jenkins是部署在本地的&#xff…

【MySQL】-索引以及树的常用数据结构分析

作者:学Java的冬瓜 博客主页:☀冬瓜的主页🌙 专栏:【MySQL】 分享:纵一苇之所如,凌万顷之茫然。——《赤壁赋》 主要内容:MySQL中索引的介绍、创建索引、使用索引;索引背后的数据结构…

Pandas提取数据的几种方式

文章目录前言Pandas读取数据的几种方式1. read_csv2. read_excel3. read_sql总结前言 快期末了,数据挖掘的大作业需要用到python的相关知识(这太难为我这个以前主学C的人了,不过没办法还是得学😂),下面是我…

集合的框架体系和Collection接口

1.集合的理解和好处 前面我们保存多个数据使用的是数组,那么数组有不足的地方,我们分析一下 1.1数组 1)长度开始时必须指定,而且一旦指定,不能更改 2)保存的必须为同一类型的元素 3)使用数组进行增加/删除元素的示例代码-比较麻烦…

通过项目下的包名获取包下的全部类

通过项目下的包名获取包下的全部类 关键点: ClassLoader.getResources() 返回给定包目录下所有资源。 是一个非静态方法,它只能通过类对象访问,如果我们尝试使用类名访问方法,那么我们将得到一个错误。 方法可能在返回资源时抛出…

2023年大学毕业生,我有话想对你说

虽然每年都说大学毕业生有多少多少,就业难,但貌似以往的经济寒冬,互联网寒冬都不如2022年2023年这么寒冷。 可以说,2022年一整年都是在裁员的声音中度过的,有的公司逐渐取消年终奖,原本熙熙攘攘的办公室&am…