前面的两小节,我分享了一下JVM的垃圾回收算法和垃圾回收器,本节中,我们来看看JVM的内存分配到底是如何进行的,作为对前面两节内存回收的补充。

从前面的内存回收中我们了解到,Hotspot JVM中的垃圾收集器的设计思路都是基于分代回收的,尽管在G1收集器不再像任何(当前已使用的)其他收集器一样,明显的把JVM堆内存区域分为新生代、老年代、永久代,但是,在逻辑上依然存在着这样的概念。为什么会出现这样的情况呢?我想大概还是因为那两个假设

那下面我主要来看看JVM堆区对象分配的一般规则:

  • 1. 对象优先在Eden区分配
  • 2. 大对象直接进入老年代(-XX:PretenureSizeThreshold=3145728 这个参数来定义多大的对象直接进入老年代)
  • 3. 长期存活的对象将进入老年代(在JDK8中测试,-XX:MaxTenuringThreshold=1的阀值设定根本没用)
  • 4. 动态对象年龄判定(虚拟机并不会永远地要求对象的年龄都必须达到MaxTenuringThreshold才能晋升老年代,如果Survivor空间中相同年龄的所有对象的大小总和大于Survivor的一半,年龄大于或等于该年龄的对象就可以直接进入老年代)
  • 5. 空间分配担保,逻辑如下(仅限6.0_24之前的JDK版本,6.0_24及之后的版本逻辑参考6)
    • 5.1 在Minor GC之前,检查老年代最大连续可用空间是否大于新生代所有对象总空间,如果是,则确认Minor GC是正常的,否则继续
    • 5.2 查看HandlePromotionFailure设置值是否允许担保失败,如果允许则继续,否则5.5;
    • 5.3 检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果是则5.4,否则5.5;
    • 5.4 尝试着进行一次Minor GC,尽管可能有风险;
    • 5.5 进行full GC。
  • 6. 只要老年代的连续空间大于(新生代所有对象的总大小或者历次晋升的平均大小)就会进行minor GC,否则会进行full GC

说上面只是一般规则,是因为,在具体的运行过程中,JVM内部的内存分配算法远比这复杂的多得多。举一个我知道的例子,TLAB(Thread Local Allocation Buffer)就是为了优化在多线程环境下,避免在内存分配的过程中锁竞争而引起的线程频繁切换而导致内存分配性能受影响而采取的优化措施。具体的优化过程,可以自行百度“Java TLAB”或者“JMM”了解更为详细的信息。当然我在后续的研究过程中,还会继续深究并分享出来。

JVM的内存管理是JVM的核心之一,如何高效的管理和回收系统中宝贵的内存资源,是Java语言编写的应用程序得以稳定、高效运行的基石,而深入理解JVM是如何做这些工作的原理,并进行多方面的实践,又是Java程序员能否编写健壮、高效的代码的基石。尽管学习了这么多,但最终只有真正在工作中运用和实践,才能才敢真正说掌握了。

参考:《深入理解Java虚拟机》

JVM(五)内存(Heap)分配的更多相关文章

  1. jvm的内存分配总结

    最近看了周志明版本的<深入理解Java虚拟机>第一版和第二版,写的很好,收获很多,此处总结一下.   jvm中内存划分:   如上图,一共分为五块,其中: 线程共享区域为: 1.java堆 ...

  2. JVM初探- 内存分配、GC原理与垃圾收集器

    JVM初探- 内存分配.GC原理与垃圾收集器 标签 : JVM JVM内存的分配与回收大致可分为如下4个步骤: 何时分配 -> 怎样分配 -> 何时回收 -> 怎样回收. 除了在概念 ...

  3. JVM堆内存相关的启动参数:年轻代、老年代和永久代的内存分配

    如果想观察JVM进程占用的堆内存,可以通过命令工具jmap或者可视化工具jvisualvm.exe.JVM这些启动参数都拥有默认值,如果想了解JVM的内存分配策略,最好手动设置这些启动参数.再通过JD ...

  4. JVM 垃圾回收机制和常见算法和 JVM 的内存结构和内存分配(面试题)

    一.JVM 垃圾回收机制和常见算法 Sun 公司只定义了垃圾回收机制规则而不局限于其实现算法,因此不同厂商生产的虚拟机采用的算法也不尽相同.GC(Garbage Collector)在回收对象前首先必 ...

  5. 1 - JVM随笔分类(java虚拟机的内存区域分配(一个不断记录和推翻以及再记录的一个过程))

    java虚拟机的内存区域分配   在JVM运行时,类加载器ClassLoader在加载到类的字节码后,交由jvm的执行引擎处理, 执行过程中需要空间来存储数据(类似于Cpu及主存),此时的这段空间的分 ...

  6. 认识JVM的内存分配

    当我们在JVM中运行一段程序代码,JVM初始运行的时候都会分配好Method Area(方法区)和Heap(堆),而JVM每遇到一个线程,就为其分配一个Program Counter Register ...

  7. Java核心:类加载和JVM内存的分配

    类的加载: 指的是将class文件的二进制数据读入到运行时数据区(JVM在内存中划分的) 中,并在方法区内创建一个class对象. 类加载器: 负责加载编译后的class文件(字节码文件)到JVM(J ...

  8. JVM的内存分配与垃圾回收策略

    自动内存管理机制主要解决了两个问题:给对象分配内存以及回收分配给对象的内存. >>垃圾回收的区域 前面的笔记中整理过虚拟机运行数据区,再看一下这个区域: 注意在这个Runtime Data ...

  9. 深入理解JVM(4)——对象内存的分配策略

    一.Java所承担的自动内存管理主要是针对对象内存的分配和回收. 二.在Java虚拟机的五块内存空间中,程序计数器.Java虚拟机栈.本地方法栈内存的分配和回收都具有确定性,一般在编译阶段就能确定需要 ...

  10. JVM总结(二):JVM的内存分配策略

    这节我们总结一下JVM中的内存分配策略.目录如下: 内存分配策略 对象优先在新生代Eden分配 大对象直接进入老年代 长期存活的对象将进入老年代 动态对象年龄判定 空间分配担保 内存分配策略 Java ...

随机推荐

  1. Python+Requests接口测试教程(1):Fiddler抓包工具

    本书涵盖内容:fiddler.http协议.json.requests+unittest+报告.bs4.数据相关(mysql/oracle/logging)等内容.刚买须知:本书是针对零基础入门接口测 ...

  2. 手把手封装数据层之DataUtil数据库操作的封装

    上一篇我们写完了数据库连接的封装 没有看的请移步上一篇关于数据库连接的内容 这次我们讲数据库操作的封装.数据库的操作就是增删改查:心再大一点就可以直接分为查询和其他. 因为查询是有返回对象的,而其他都 ...

  3. JSP慕课网之Session

    会话保存在服务器的内存里. sessionId可以通过进入http://localhost:8888/进入Tomcat的Manager App进行查看,点击项目的sessions可以看到session ...

  4. java面向对象(一)

    [toc] 面向对象 我们都说java是面向对象的编程语言,那什么是面向对象呢?什么是类呢?什么是方法呢? 类.对象.方法 类是对象的抽象定义,对象是类的具体实例. 类:指的是一类东西,比如汽车,人类 ...

  5. 数据库面试技巧,通过JDBC展示自己专业性,摘自java web轻量级开发面试教程

    这篇文章是我之前写的博文 数据库方面的面试技巧,如何从建表方面展示自己能力 和 面试技巧,如何通过索引说数据库优化能力,内容来自Java web轻量级开发面试教程是一个系列的,通过面试官的视角和大家分 ...

  6. cobbler实现自动安装

    author:JevonWei 版权声明:原创作品 cobbler 配置目录 配置文件目录 /etc/cobbler /etc/cobbler/settings : cobbler 主配置文件 /et ...

  7. NSA武器库知识整理

    美国国家安全局(NSA)旗下的"方程式黑客组织"(shadow brokers)使用的部分网络武器被公开,其中包括可以远程攻破全球约70%Windows机器的漏洞利用工具. 其中, ...

  8. poj 1384完全背包

    题意:给出猪罐子的空质量和满质量,和n个硬币的价值和质量,求猪罐子刚好塞满的的最小价值. 思路:选择硬币,完全背包问题,塞满==初始化为无穷,求最小价值,min. 代码: #include<io ...

  9. 【Java IO流】对象的序列化和反序列化

    对象的序列化和反序列化 1)对象序列化,就是将Object对象转换成byte序列,反之叫对象的反序列化. 2)序列化流(ObjectOutputStream),是字节的过滤流—— writeObjec ...

  10. 【Socket编程】通过Socket实现TCP编程

    通过Socket实现TCP编程 Socket通信 : 1.TCP协议是面向对象连接.可靠的.有序的,以字节流的方式发送数据. 2.基于TCP协议实现网络通信的类: 客户端----Socket类 服务器 ...