博客
关于我
JVM年轻代,老年代,永久代详解
阅读量:431 次
发布时间:2019-03-06

本文共 1276 字,大约阅读时间需要 4 分钟。

前言

最近被问到内存区域的相关问题时,发现一些概念还不够清晰。为了更好地理解和分享,我整理了以下内容,主要介绍了Java中的内存区域划分,包括年轻代、老年代和永久代,以及垃圾回收算法的基本知识。接下来,我们将从堆的整体结构入手,逐步深入了解每个区域的特点和作用。

堆整体

在Java中,堆是垃圾回收机制的核心区域,主要用于存储类实例和数组。堆被划分为两个主要区域:年轻代和老年代。值得注意的是,在早期的Java版本中还存在一个称为永久代的区域,但现在在JDK 8及以后的版本中,永久代已经被元空间取代了。

堆的划分目的是为了优化垃圾回收效率。新对象首先会被分配到年轻代中,这也是为什么年轻代垃圾回收效率较高的原因。当垃圾回收机制(Minor GC)运行时,只会回收年轻代中的对象。而老年代的垃圾回收则需要触发Major GC,也称为Full GC,这会导致程序暂停较长时间。

年轻代

年轻代是存放新对象的主要区域,默认占堆内存的1/15。为了更灵活地配置年轻代的大小,可以通过-Xmn参数设置固定值,或者通过-XX:newratio参数调整年轻代与老年代的比例。

年轻代的对象生命周期通常较短,容易被垃圾回收机制快速回收。为了进一步优化垃圾回收效率,年轻代被划分为三个子区域:Eden、Survivor空间。默认比例为8:1:1。垃圾回收时,Eden区中的活对象会被复制到Survivor区中,逐步清理Eden区的内存。如果对象连续存活15次,会被移至老年代中。这种机制不仅提高了垃圾回收效率,还避免了老年代的内存碎片问题。

老年代

老年代存放的是存活时间较长的对象,通常需要被垃圾回收的次数较少。然而,这并不意味着老年代的垃圾回收效率高于年轻代。实际上,老年代的垃圾回收需要触发Full GC,而Full GC会暂停程序运行,导致性能下降。

Full GC采用标记-清除算法,这种算法虽然简单,但会导致内存碎片问题。为了减少内存碎片,可以使用标记-整理算法。不过,Full GC的执行时间通常比Minor GC长得多,特别是在老年代内存占用较高的情况下。因此,在实际应用中,需要尽量减少老年代的垃圾回收触发次数。

永久代

在早期的Java版本中,永久代是存放JVM运行时类和库的区域,与堆是分开管理的。永久代的内存溢出问题(称为PermanenGen space overflow)在过去曾是Java性能优化中的一个重要课题。然而,在JDK 8及以后的版本中,永久代被元空间取代了。

元空间

元空间(Metaspace)是JDK 8后替代永久代的区域,主要用于存储类元数据。与永久代不同,元空间并不占用堆内存,而是使用本地内存。元空间的大小可以通过以下参数进行配置:
  • -XX:MetaspaceSize:初始元空间的大小,默认为物理内存的一半。
  • -XX:MaxMetaspaceSize:最大元空间大小,默认为无限。

元空间的垃圾回收过程会剥离元数据,简化垃圾回收的复杂性,提高整体效率。与永久代相比,元空间的内存管理更加灵活,也避免了内存碎片问题。

转载地址:http://rruyz.baihongyu.com/

你可能感兴趣的文章
php的web路径获取
查看>>
php的一些小笔记--字符串
查看>>
php的几种运行模式CLI、CGI、FastCGI、mod_php
查看>>
php的四大特性八大优势
查看>>
RabbitMQ
查看>>
PHP的威胁函数与PHP代码审计实战
查看>>
PHP的引用举例
查看>>
PHP相关代码
查看>>
RabbitMQ
查看>>
php知识点记录
查看>>
PHP知识笔记:CGI, FastCGI, PHP-CGI, PHP-FPM, Spawn-FCGI区别
查看>>
PHP第三方登录—OAuth2.0协议
查看>>
php筛选js,php如何多条件筛选js代码
查看>>
R730服务器做了raid的硬盘,插在R720上面可以用吗?
查看>>
PHP类数组式访问(ArrayAccess接口)
查看>>
PHP系列:浅谈PHP中isset()和empty() 函数的区别
查看>>
PHP索引数组unset的坑-array_values解决方案
查看>>
PHP索引数组排序方法整理(冒泡、选择、插入、快速)
查看>>
PHP线程安全和非线程安全
查看>>
R3LIVE开源项目常见问题解决方案
查看>>