java内存的分配策略
1.概述
本文是《深入理解java虚拟机》(周志明著)3.6节的笔记整理,文章结构也与书上相同,讲述的是几条最普遍的内存分配策略。
2.对象优先在Eden分配
** 大多数情况下,对象在新生代Eden去中分配,(注:java堆中的新生代可分为Eden区和两个Survivor区),当Eden区中没有足够的空间进行分配时,虚拟机将发起一次Minor GC。 **
Minor GC 和 Full GC的区别
- 新生代GC(Minor GC):指的是发生在新生代中的垃圾收集动作,java对象的创建和回收非常频繁,所以Mnior GC非常频繁,一般回收速度也比较快。
- 老年代GC(Major GC/Full FC):指发生在老年代中的GC,出现了Major GC经常会伴随至少一次的Minor GC(并非绝对),Major GC的速度一般会比Minor GC慢10倍以上。
3.大对象直接进入老年代
大对象是指,需要大量连续内存空间的java对象(写程序的时候应该避免“短命大对象”),经常出现大对象,容易导致内存还有不少空间时,就提前触发垃圾收集以获取足够的连续空间来分给他们。
虚拟机提供-XX:PretenureSizeThreshold参数,令大于这个设置值的对象直接进入老年代,这么做为目的是为了避免在Eden以及两个Survivor区之间发生大量的内存复制(新生代的垃圾收集算法采用复制算法)。
4.长期存活的对象将进入老年代
虚拟机给每个对象定义一个对象年龄(Age)的计数器,如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到Survivor空间中,并且对象年龄设为1.其在Survivor中没经历一次Minior GC,Age就加1,当其Age增加到一定程度(默认15岁),就将其晋升到老年代。年龄阈值可以通过参数-XX:MxTenuringThreshold设置。
5.动态对象的年龄判定
为了能更好的适应不同程序的内存状况,虚拟机不是永远地要求对象的年龄必须达到MaxTenuringThreshold才能晋升老年代,如果Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或者等于该年龄的对象就可以直接进入老年代。
6.空间分配担保
在发生Minor GC之前,虚拟机会先检查老年代中最大可用连续空间是否大于新生代所有对象总空间,如果这个条件成立,那么Minor GC可以确保是安全的。如果不成立,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。如果允许,那么会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于将尝试进行一次Minor GC。如果小于或者HandlePromotionFailure设置为不允许,那这时就改为一次Full GC。
分配担保解释:
新生代使用复制算法完成垃圾收集,为了节约内存Survivor的设置的比较小,当Minor GC后如果还有大量对象存活,超过了一个Survivor的内存空间,这时就需要老年代进行分配担保,把Survivor中无法容纳的对象直接进入老年代。若虚拟机检查老年代中最大可用连续空间大于新生代所有对象总空间那么就能保证不需要发生Full GC,因为老年代的内存空间够用。反之,如果老年代中最大可用连续空间小于新生代所有对象总空间就需要在尝试Minor GC失败后进行Full Gc或者直接Full GC。
java内存的分配策略的更多相关文章
- Tensorflow2对GPU内存的分配策略
一.问题源起 从以下的异常堆栈可以看到是BLAS程序集初始化失败,可以看到是执行MatMul的时候发生的异常,基本可以断定可能数据集太大导致memory不够用了. 2021-08-10 16:38:0 ...
- 深入理解JVM(4)——对象内存的分配策略
一.Java所承担的自动内存管理主要是针对对象内存的分配和回收. 二.在Java虚拟机的五块内存空间中,程序计数器.Java虚拟机栈.本地方法栈内存的分配和回收都具有确定性,一般在编译阶段就能确定需要 ...
- java内存的分配和管理
常用的三个内存空间 栈内存 ,堆内存 ,方法区 栈内存存储的内容: 局部变量. 函数(栈中的局部变量,需要手动赋值.当变量,或者函数执行完毕,就自动被释放) 堆内存,存储的内容 :全局变量.数据容器. ...
- Java内存区域分配基恩内存溢出异常
- JAVA内存存储分配粗略讲解
以String类型为例:String s1 = "ABC"; String s2 = "ABC"; String s3 = new String("A ...
- java内存模型(线程共享部分)
1.元空间(MetaSpace)与永久代(PermGen)的区别? ----> 1.1 元空间使用的是本机内存(这样的好处是,可以使用的内存空间变大了,没有OutOfMemoryError:Pe ...
- java中内存分配策略及堆和栈的比较
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间 ...
- 深入理解java虚拟机(2)------垃圾收集器和内存分配策略
GC可谓是java相较于C++语言,最大的不同点之一. 1.GC回收什么? 上一篇讲了内存的分布. 其中程序计数器栈,虚拟机栈,本地方法栈 3个区域随着线程而生,随着线程而死.这些栈的内存,可以理解为 ...
- java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收集(Garbage Collection,下文简称GC),大部分人都把这项 ...
随机推荐
- qt4.8转qt5.4
1.头文件包含 #include <QtGui/QProgressBar> #include <QtGui/QProgressDialog> #include ...
- gatttool的使用
1.使能hci接口 # hciconfig hci0 up 2.使用hcitool搜索BLE设备 # hcitool lescan LE Scan ...D0:39:72:BE:D2:26 (unkn ...
- [Java]通过java获取计算机名
通过java获取计算机名 String hostname = "Unknown"; try { InetAddress addr; addr = InetAddress.getLo ...
- PHP(八)数组
- java并发编程实战:第十六章----Java内存模型
一.什么是内存模型,为什么要使用它 如果缺少同步,那么将会有许多因素使得线程无法立即甚至永远看到一个线程的操作结果 编译器把变量保存在本地寄存器而不是内存中 编译器中生成的指令顺序,可以与源代码中的顺 ...
- ETL的测试
二.ETL测试过程: 在独立验证与确认下,与任何其他测试一样,ETL也经历同样的阶段. 1)业务和需求分析并验证. 2)测试方案编写 3)从所有可用的输入条件来设计测试用例和测试场景进行测试 4)执行 ...
- Javascript设计模式理论与实战:工厂方法模式
本文从简单工厂模式的缺点说起,引入工厂方法模式,介绍的工厂方法模式的基本知识,实现要点和应用场景,最后举例进行说明工厂方法模式的应用.在之前的<Javascript设计模式理论与实战:简单工厂模 ...
- Spring中ApplicationContext和beanfactory区别---解析二
一.BeanFactory 和ApplicationContext Bean 工厂(com.springframework.beans.factory.BeanFactory)是Spring 框架最核 ...
- 多彩浏览器win10版 隐私声明
(一)隐私保护 the app need internet access,we won't need your private information, in other words, your i ...
- 【题解】 AGC029-A Irreversible operation
传送门 定位:思维好题. 考虑无论如何每一个W都会和前面的B在一起交换一次,所以直接求和就好了. 注意long long的使用. #include<stdio.h> #include< ...