1、对象优先在Eden区分配

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

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

2、大对象直接进入老年代

所谓的大对象是指需要大量连续内存空间的Java对象。大对象对虚拟机的内存分配来说是一个坏消息,经常出现大对象导致内存还有不少空间时就提前触发垃圾回收以获得足够的连续空间来“安置”大对象。

虚拟机提供了一个-XX:pretenureSizeThreshold参数,令大于这个设置值的对象直接在老年代分配,这样做的目的是避免在Eden及两个Survivor区域间发生大量的内存复制。

3、长期存活的对象将直接进入老年代

虚拟机采用分代收集的思想管理内存,则内存回收即必须识别哪些对象应该放在老年代,哪些对象应该放在新生代。为了做到此,虚拟机给每个对象设置了年龄计数器(Age)。

如果对象在Eden区域出生并且经过一次Minor GC后依然存活,并且被Survivor区域容纳话没,被移至Survivor区域,年龄+1。对象在Survivor区域每“熬过”一次Minor GC,年龄就+1,当其年龄增加到一定程度(默认15),就会晋升至老年代。

对象晋升老年代的年龄阈值,可以通过-XX:MaxTenuringThreshold参数设置。

4、动态对象年龄判定

为了更好的适应不同程序的内存状况,虚拟机并不是永远的要求对象的年龄必须达到MaxTenuringThreshold才能晋升老年代,如果在Survivor空间中相同年龄所有对象大小总和大于Survivor空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代,无需等到MaxTenuringThreshold中要求的年龄。

5、空间分配担保

在发生Minor GC之前,虚拟机会先检查老年代的最大可用的连续空间是否大于新生代所有对象的总空间,如果条件成立,那么Minor GC可以确保是安全的。如果不成立,则虚拟机会查看HandlePromotionFailure设置的值是否允许担保失败。如果允许,那么会继续检查老年代最大可用的连续空间是否大于历次晋升老年代对象的平均大小,如果大于,将尝试进行一次Minor GC,尽管这次Minor GC是有风险的;如果小于,或者HandlePromotionFailure设置不允许冒险,那么这时要改为进行一次Full GC。

JVM——内存分配与回收策略的更多相关文章

  1. jvm内存分配和回收策略

    在上一篇中,已经介绍了内存结构是什么样的. 这篇来介绍一下 内存是怎么分配的,和怎么回收的.(基本取自<深入理解Java虚拟机>一书) java技术体系中所提倡的自动内存管理最终可以归结为 ...

  2. JVM 内存分配和回收策略

    对象的内存分配,主要是在java堆上分配(有可能经过JIT编译后被拆为标量类型并间接地在栈上分配),如果启动了本地线程分配缓冲,将按线程优先在TLAB上分配.少数情况下也是直接分配到老年代,分配规则不 ...

  3. A4. JVM 内存分配及回收策略

    [概述] Java 技术体系中所提倡的自动内存管理最终可以归结为自动化地解决两个问题:给对象分配内存以及回收分配给对象的内存. 对象的内存分配,往大方向讲,就是在堆上分配,对象主要分配在新生代的 Ed ...

  4. JVM内存分配与回收策略

    对象优先在Eden分配 大多数情况下,对象在新生代Eden区中分配. 当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC. Minor GC:新生代GC,指发生在新生代的垃圾收集动作 ...

  5. Java虚拟机垃圾回收:内存分配与回收策略 方法区垃圾回收 以及 JVM垃圾回收的调优方法

    在<Java对象在Java虚拟机中的创建过程>了解到对象创建的内存分配,在<Java内存区域 JVM运行时数据区>中了解到各数据区有些什么特点.以及相关参数的调整,在<J ...

  6. JVM垃圾回收器、内存分配与回收策略

    新生代垃圾收集器 1. Serial收集器 serial收集器即串行收集器,是一个单线程收集器. 串行收集器在进行垃圾回收时只使用一个CPU或一条收集线程去完成垃圾回收工作,并且会暂停其他的工作线程( ...

  7. JVM学习十 -(复习)内存分配与回收策略

    内存分配与回收策略 对象的内存分配,就是在堆上分配(也可能经过 JIT 编译后被拆散为标量类型并间接在栈上分配),对象主要分配在新生代的 Eden 区上,少数情况下可能直接分配在老年代,分配规则不固定 ...

  8. 最简单例子图解JVM内存分配和回收

    一.简介 JVM采用分代垃圾回收.在JVM的内存空间中把堆空间分为年老代和年轻代.将大量(据说是90%以上)创建了没多久就会消亡的对象存储在年轻代,而年老代中存放生命周期长久的实例对象.年轻代中又被分 ...

  9. 最简单例子图解JVM内存分配和回收(转)

    本文转自http://ifeve.com/a-simple-example-demo-jvm-allocation-and-gc/ http://www.idouba.net/a-simple-exa ...

随机推荐

  1. Ubuntu16.04安装apache hive

    0.常规配置操作可参照以下网址: 0.1 Ubuntu安装hive,并配置mysql作为元数据库http://dblab.xmu.edu.cn/blog/install-hive/ ------以下为 ...

  2. RocketMQ源码详解 | Broker篇 · 其三:CommitLog、索引、消费队列

    概述 上一章中,已经介绍了 Broker 的文件系统的各个层次与部分细节,本章将继续了解在逻辑存储层的三个文件 CommitLog.IndexFile.ConsumerQueue 的一些细节.文章最后 ...

  3. 好好的 Tair 排行榜不用,非得自己写?20 行代码实现高性能排行榜

    TairZset 是阿里云自研的可实现任意维度 double 类型的分值排序的数据结构,借助 Tair 客户端同时可实现扩展性,即可以将计算任务分布至多个数据节点完成,实现分布式排行榜能力.本文介绍了 ...

  4. ONVIF客户端中预置位设置代码实现过程

    simpleOnvif的功能:提供支持Windows.Linux.arm.Android.iOS等各种平台的SDK库,方便集成,二次开发 之前跟大家分享了我们安徽思蔷信息科技的simpleOnvif的 ...

  5. 性能工具之代码级性能测试工具ContiPerf

    前言 做性能的同学一定遇到过这样的场景:应用级别的性能测试发现一个操作的响应时间很长,然后要花费很多时间去逐级排查,最后却发现罪魁祸首是代码中某个实现低效的底层算法.这种自上而下的逐级排查定位的方法, ...

  6. 'pybot' 不是内部或外部命令,也不是可运行的程序 或批处理文件

    在dos下运行pybot --version提示不是内部命令 这是pip list 打印信息: 解决方法: 在python/Scripts目录下加一个pybot.bat 文件 内容为: @Echo o ...

  7. 为什么不直接去Arraylist list = new Arraylist();而是直接通过List list = new ArrayList();使用接口的好处

    ArrayList不是继承List接口,是实现了List接口. 你写成ArrayList arrayList = new ArrayList();这样不会有任何问题.和List list = new ...

  8. 大一C语言学习笔记(8)---指针篇--动态内存是什么?与静态内存有什么区别?怎么使用动态内存,有什么需要注意的地方?

    静态内存指的是在编译时系统自动给其分配的内存,运行结束后会自动释放:静态内存是在栈中分配的: 动态内存是我们程序员手动分配的内存,正常情况下,程序运行结束后,也不会自动释放,所以为了避免发生未知的错误 ...

  9. 菜鸡的Java笔记 第十一 - java 封装性

    1.1封装的基础实现.        封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口.面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治.封装的对象,这些对象通过一个受保 ...

  10. Django 项目配置拆分独立

    目录 一.创建配置目录 二.创建基础配置文件 三.创建各个环境的配置 四.调整settings.py 五.程序使用 六.目录结构 Django 项目中,我们默认的配置是都在 settings.py 文 ...