Code Ease Code Ease
  • 个人博客网站 (opens new window)
  • 好用的工具网站 (opens new window)
  • Java核心基础
  • 框架的艺术
  • 分布式与微服务
  • 开发经验大全
  • 设计模式
  • 版本新特性
数据库系列
大数据+AI
  • xxl-job
运维与Linux
  • 基于SpringBoot和BootStrap的论坛网址
  • 基于VuePress的个人博客网站
  • 基于SpringBoot开发的小功能
  • 做一个自己的IDEA插件
程序人生
关于我
  • 分类
  • 标签
  • 归档

神秘的鱼仔

你会累是因为你在走上坡路
  • 个人博客网站 (opens new window)
  • 好用的工具网站 (opens new window)
  • Java核心基础
  • 框架的艺术
  • 分布式与微服务
  • 开发经验大全
  • 设计模式
  • 版本新特性
数据库系列
大数据+AI
  • xxl-job
运维与Linux
  • 基于SpringBoot和BootStrap的论坛网址
  • 基于VuePress的个人博客网站
  • 基于SpringBoot开发的小功能
  • 做一个自己的IDEA插件
程序人生
关于我
  • 分类
  • 标签
  • 归档
服务器
  • Java核心基础

    • 基础篇

    • 集合类

    • JVM虚拟机

      • JVM的内存分代,这篇文章帮你理一理
        • (一)JVM分代
        • (二)方法区、永久代和元空间的区别
        • (三)什么是新生代和老年代
        • (四)总结
      • 用几张图深度剖析Java运行时数据区
      • JVM垃圾回收机制是怎样的,何时触发YoungGC或FullGC操作,一文搞定
      • 关于垃圾收集器你了解多少?一文总结七大垃圾收集器
      • 深入浅出CMS垃圾收集器
      • 图解类加载器和双亲委派机制,一看就懂
      • 关于JVM调优,我理了一些工具和思路出来
      • 两张图让你快速读懂JVM字节码指令
      • 从JVM角度思考--如何预估线上环境机器资源大小
    • Java并发

  • 框架的艺术

  • 分布式与微服务

  • 开发经验大全

  • 版本新特性

  • Java
  • Java核心基础
  • JVM虚拟机
CodeEase
2023-09-16
目录

JVM的内存分代,这篇文章帮你理一理

作者:鱼仔
博客首页: codeease.top (opens new window)
公众号:Java鱼仔

# (一)JVM分代

堆内存是JAVA虚拟机所管理的内存最大的一块,Java堆被所有线程共享,几乎所有的对象实例都是在堆中分配内存,因此Java的堆是垃圾回收的主要区域。

JVM的内存分代讲的就是堆内存的分代,为了更加高效的回收垃圾,将内存划分为了多个generation(代)。

最常听到的一种说法是:JVM分代可以划分为新生代、老年代、永久代。但是也经常听到还有一种叫做元空间的东西。希望看完这篇文章之后对于上面的疑问可以消失。

# (二)方法区、永久代和元空间的区别

首先来看一下JDK1.7和JDK1.8的运行时数据区差别: JDK1.8之前:

1-1.png

JDK1.8之后:

1-2.jpeg

最显著的区别是方法区消失了,元空间出现在了直接内存里。

方法区、永久代和元空间的区别可以用一句话来解释:方法区是虚拟机是虚拟机的一种规范,永久代是HotSpot虚拟机对方法区的一种实现,而到了JDK1.8后,这种实现变成了元空间。

永久代存储类信息、常量、静态变量、即时编译器编译后的代码等数据,并且永久代必须指定大小限制,因此就会导致性能问题和内存溢出的问题。永久代会给GC带来不必要的复杂性。

因此出现了直接使用了本地内存的元空间,元空间可以设置限制,也可以不设置,它的大小仅受本地内存限制。

# (三)什么是新生代和老年代

新生代和老年代是垃圾回收最主要的区域,我们也主要来讲解这两个区域,看下图

1-3.png

新生代和老年代都在堆内存中,新生代和老年代所占的默认比例为1:2,其中一个新生代又由一个Eden区+两个survivor区组成,默认比例为8:1:1。至于为什么这么设置,就和所采用的垃圾回收算法有关。

首先讲一下新生代,YoungGC对应于新生代:

第一次YGC只回收eden区域,回收后大多数(百分之九十八左右)的对象会被回收,活着的对象通过复制算法进入Survivor0(后续用S0和S1代替)。

再次YGC后,eden+S0中活着的对象进入S1。

再次YGC,eden+S1中活着的对象进入到S0。依次循环。看到这里我相信你已经明白了为什么要设置两个survivor区域了。

当一个对象的年龄(经历的YGC次数)足够时(传统的垃圾回收器一般是15,CMS垃圾回收器是6),进入老年代。

如果遇到一个对象S区装不下,则直接进入老年代。

老年代的垃圾回收或称叫做FullGC,当老年代空间不足时,就会触发FullGC;另外,如果元空间区域的内存达到了所设定的阈值-XX:MetaspaceSize=,也会触发FullGC。

FullGC采用的是标记整理算法,这个算法的效率是比较低的,因为它要标记出或者的对象,然后移到内存的一侧,最后再清空区域外的内存。这个过程会十分消耗时间。

因此优化JVM最重要的一点就是优化FGC,尽可能的不要执行FGC。

# (四)总结

JVM是Java领域十分重要的知识点,要想掌握到一定程度也不容易,不过慢慢积累总能达到厚积薄发。我是鱼仔,我们下期再见!

上次更新: 2025/04/29, 17:22:06
ConcurrentHashMap的底层原理分析
用几张图深度剖析Java运行时数据区

← ConcurrentHashMap的底层原理分析 用几张图深度剖析Java运行时数据区→

最近更新
01
AI大模型部署指南
02-18
02
半个月了,DeepSeek为什么还是服务不可用
02-13
03
Python3.9及3.10安装文档
01-23
更多文章>
Theme by Vdoing | Copyright © 2023-2025 备案图标 浙公网安备33021202002405 | 浙ICP备2023040452号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式