jvm内存分配与回收策略

自动内存管理

解决两个问题

自动给对象分配内存

对象一般堆上分配(而实际上也有可能经过即时编译后被拆散为标量类型并间接地在栈上分配)

新生对象通常会分配在新生代,少数情况下(例如对象大小超过一定阈值)也可能会直接分配在老年代

实际对象分配的规则并不是固定的,具体取决于虚拟机使用的是哪一种垃圾收集器以及虚拟机中与内存相关参数的设定

自动回收分配给对象的内存(垃圾收集器做的事)

对象优先在Eden分配

大多数情况下,对象在新生代Eden区中分配当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC。

-XX:+PrintGCDetails:收集器日志参数,告诉虚拟机在发生垃圾收集行为时打印内存回收日志,并且在进程退出的时候输出当前的内存各区域分配情况。

image-20230927232825248

参数含义:

-Xms20M(初始) -Xmx20M(最大):堆内存固定20m

-Xmn10M:10MB分配给新生代(剩下的10MB分配给老年代)

-XX:SurvivorRatio=8:新生代中Eden区与一个Survivor区的空间比例是8:1

代码:

public class AllocationTest {private static final int _1MB = 1024 * 1024;public static void main(String[] args) {byte[] a1, a2, a3, a4;a1 = new byte[2 * _1MB];a2 = new byte[2 * _1MB];a3 = new byte[2 * _1MB];a4 = new byte[4 * _1MB]; // 出现一次Minor GC}
}

控制台打印:

image-20230927234410189

上述老年代占用4M跟下一节阈值默认配置有关。

Minor GC、Major GC以及Full GC因为不同垃圾收集器以及不同JDK版本触发条件都不尽相同

Minor GC:新生代垃圾收集

Major GC:老年代垃圾收集

Full GC:全堆垃圾收集

思路基本都是内存不够用了进行垃圾收集

大对象直接进入老年代

大对象指需要大量连续内存空间的Java对象最典型的大对象便是那种很长的字符串,或者元素数量很庞大的数组

Java虚拟机中要避免大对象的原因

分配空间时,容易导致内存明明还有不少空间时就提前触发垃圾收集,以获取足够的连续空间才能安置好大对象,而当复制对象时,大对象意味着高额的内存复制开销

-XX:PretenureSizeThreshold:指定大于该设置值的对象直接在老年代分配(默认值为3145728字节即3M)

【-XX:PretenureSizeThreshold=3145728】,超过3MB的对象都会直接在老年代进行分配。

-XX:PretenureSizeThreshold参数仅在使用Parallel Scavenge(并行年轻代)和Parallel Old(并行老年代)【JDK8默认组合】收集器组合时以及Serial和ParNew两款新生代收集器有效。

长期存活的对象将进入老年代

HotSpot虚拟机中多数收集器都采用了分代收集来管理堆内存,那内存回收时就必须能决策哪些存活对象应当放在新生代,哪些存活对象放在老年代中。

虚拟机给每个对象定义了一个对象年龄(Age)计数器,存储在对象头中

对象通常在Eden区里诞生,如果经过第一次Minor GC后仍然存活,并且能被Survivor容纳,该对象会被移动到Survivor空间中,并且将其对象年龄设为1岁。对象在Survivor区中每熬过一次Minor GC,年龄就增加1岁,当它的年龄增加到一定程度(默认为15),就会被晋升到老年代中

-XX:MaxTenuringThreshold:设置对象晋升老年代的年龄阈值(默认15)

动态对象年龄判定

为了能更好地适应不同程序的内存状况,

HotSpot虚拟机并不是永远要求对象的年龄必须达到-XX:MaxTenuringThreshold才能晋升老年代

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

空间分配担保

在发生Minor GC之前,虚拟机先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,大于则保证这次Minor GC是安全的,否则看参数-XX:HandlePromotionFailure:是否允许担保失败;如果允许,继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,大于,将尝试进行一次Minor GC,小于则进行一次Full GC。

JDK 6Update 24之后规则变为只要老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小,就会进行Minor GC,否则将进行Full GC。(-XX:HandlePromotionFailure参数不会再影响到虚拟机的空间分配担保策略

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

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

相关文章

[C++网络协议] 优于select的epoll

1.epoll函数为什么优于select函数 select函数的缺点: 调用select函数后,要针对所有文件描述符进行循环处理。每次调用select函数,都需要向该函数传递监视对象信息。 对于缺点2,是提高性能的最大障碍。因为,套接字是…

Python爬虫实战案例——第六例

文章中所有内容仅供学习交流使用,不用于其他任何目的!严禁将文中内容用于任何商业与非法用途,由此产生的一切后果与作者无关。若有侵权,请联系删除。 目标:去哪儿网指定城市人气值最高的15个景点评论数据采集 地址&a…

微信小程序开发基础(二)基本组件

本帖开始介绍小程序中的一些基本组件~ 微信小程序是一种轻量、快速、跨平台的应用程序,是微信公众号的重要组成部分。随着微信小程序的普及,越来越多的开发者和企业开始使用微信小程序来搭建自己的应用,但是对于初次接触微信小程序的开发者…

排序:败者树和置换选择排序(解决外部排序中的优化问题)

1.算法目的(败者树) 解决多路平衡归并带来的问题。 在外部排序中,使用k路平衡归并策略, 选出一个最小元素需要对比关键字(k-1)次, 导致内部归并所需时间增加。(可用“败者树”进行优化) 2.败者树的定义 …

【C++11】多线程

多线程创建线程thread提供的成员函数获取线程id的方式线程函数参数的问题线程join场景和detach 互斥量库(mutex)mutexrecursive_mutexlock_guard 和 unique_lock 原子性操作库(atomic)条件变量库(condition_varuable&a…

一文读懂集合竞价,建议收藏,读完少交学费

集合竞价每个时间段交易规则及作用都不一样,了解集合竞价的规则,有利于琢磨主力的意图。 大部分同学都不是很关心集合竞价,也不知道如何利用集合竞价买卖股票。如上图所示,有同学在9点15看着股票涨停,立马冲进去&…

【切片】基础不扎实引发的问题

本次文章主要是来聊聊关于切片传值需要注意的问题,如果不小心,则很容易引发线上问题,如果不够理解,可能会出现奇奇怪怪的现象 问题情况: 小 A 负责一个模块功能的实现,在调试代码的时候可能不仔细&#x…

UE蓝图学习(从Unity3D而来)

一、UE组件对比Unity3D,从Unity3D过渡来学的角度出发,可以理解为在 空物体下放置子物体。UE没有U3D那种可以将组件挂在自身空物体上面。 二、UE 蓝图的情境提示,必须先找到相应的类型,对象对象、事件事件,才能找到相应…

云原生Kubernetes:Pod控制器

目录 一、理论 1.Pod控制器 2.Deployment 控制器 3.SatefulSet 控制器 4.DaemonSet 控制器 5.Job 控制器 6.CronJob 控制器 二、实验 1.Deployment 控制器 2.SatefulSet 控制器 3.DaemonSet 控制器 4.Job 控制器 5.CronJob 控制器 三、问题 1. showmount -e 报错…

QT窗口的设置、按钮的创建和对象树的概念

目录 设置窗口属性 按钮的创建 对象树 对象树的概念 构建和析构的顺序问题 设置窗口属性 在Qt官方手册中查找QWidget相关信息 或者在QT软件帮助一栏直接搜索QWidget 即可找到一些要寻找的设置属性的函数 将代码写在构造函数中 widget.cpp #include "widget.h"…

1200*A. Flipping Game(前缀和)

解析&#xff1a; 100数据量&#xff0c;两层遍历每个区间&#xff0c;然后前缀和计算1的个数&#xff0c;维护最大值即可。 #include<bits/stdc.h> using namespace std; #define int long long const int N110; int n,a[N],res,sum[N]; signed main(){scanf("%ll…

保姆级 -- Zookeeper超详解

1. Zookeeper 是什么(了解) Zookeeper 是一个 分布式协调服务 的开源框架, 主要用来解决分布式集群中应用系统的一致性问题, 例如怎样避免同时操作同一数据造成脏读的问题. ZooKeeper 本质上是 一个分布式的小文件存储系统 . 提供基于类似于文件系统的目录树方式的数据存储, …

常见的7种分布式事务解决方案(2pc,3pc,Tcc,Seta、本地事务....)

一 分布式事务 1.1 分布式事务 在分布式系统中一次操作需要由多个服务协同完成&#xff0c;这种由不同的服务之间通过网络协同完成的事务称为分布式事务。 1.首先满足事务特性&#xff1a;ACID 2.而在分布式环境下&#xff0c;会涉及到多个数据库 总结&#xff1a;分布式事务…

C运算符和控制语句

几乎每一个程序都需要进行运算&#xff0c;对数据进行加工处理&#xff0c;否则程序就没有意义了。要进行运算&#xff0c;就需规定可以使用的运算符。 C语言的运算符范围很宽&#xff0c;把除了控制语句和输人输出以外的几乎所有的基本操作都作为运算符处理。 运算符分类1 除…

Apache Flume

Flume 1.9.0 Developer Guide【Flume 1.9.0开发人员指南】 Introduction【介绍】 摘自&#xff1a;Flume 1.9.0 Developer Guide — Apache Flume Overview【概述】 Apache Flume is a distributed, reliable, and available system for efficiently collecting, aggregati…

Docker 安装Redis(集群)

3主3从redis集群配置 1、新建6个docker容器 redis 实例 docker run -d --name redis-node-1 --net host --privilegedtrue -v /data/redis/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381 docker run -d --name redis-node-2 --ne…

C理解(二):指针,数组,字符串,函数

本文主要探讨指针&#xff0c;数组&#xff0c;字符串&#xff0c;函数 指针 int *p; 未绑定:*表示p为指针变量,占4字节 int a 1;p &a; 绑定:p与a地址绑定即p中存放a的地址 *p *p 1; 解引用:p间接访问a的存储空间…

九、Delay函数

1、两个延时函数 vTaskDelay&#xff1a;至少等待指定个数的Tick Interrupt才能变为就绪态。vTaskDelayUntil&#xff1a;等待到指定的绝对时刻&#xff0c;才能变为就绪态。 2、函数原型 /* xTicksToDelay: 等待多少个Tick */ void vTaskDelay( const TickType_t xTicksToD…

Android Studio 的android.jar文件在哪儿

一般在&#xff1a;C:\Users\admin\AppData\Local\Android\Sdk\platforms\android-33下&#xff08;不一定是33&#xff0c;这个得看你Android Studio->app->builde.gradle的targetSdk是多少&#xff09; 怎么找&#xff1a; 1.打开Android Studio 粘贴地址后&#xff0…

13.(开发工具篇github)如何在GitHub上上传本地项目

一:创建GitHub账户并安装Git 二:创建一个新的仓库(repository) 三、拉取代码 git clone https://github.com/ainier-max/myboot.git git clone git@github.com:ainier-max/myboot.git四、拷贝代码到拉取后的工程 五、上传代码 (1)添加所有文件到暂存