当前位置:首页 > 内存 > 正文

内存回收算法

  • 内存
  • 2024-07-02 14:23:00
  • 9217

一、2022年完全最全JVM讲解(最新版2W字总结)


深入剖析:2022年JVM内存管理和垃圾回收机制全面解读

Java虚拟机(JVM)的内存区域分为两部分:私有区域和共享区域。每个线程都有一个独立的程序计数器(用于跟踪当前正在执行的字节码)、虚拟机堆栈(存储方法调用上下文)和本地方法区(存储本地代码和常量)。共享区主要涉及JAVA堆和方法区。堆用于存储对象和数组,分为新生代和老年代,对应不同的生命周期和垃圾回收策略。


新生代和老年代

新生代是物品的诞生地,Eden区主要用于创建物品。经过MinorGC(复制算法)后,幸存的对象会被移动到Survivor区或者老年代。新一代的废物收集旨在快速响应,而老一代则负责管理持久的物品。当空间不够或新对象较大时,会触发MajorGC(标记清除或标记碎片整理),从而导致。内存碎片和更长的生命周期。


元数据区域和垃圾收集算法

Java8之后,元数据区域取代了持久代、存储类和元数据信息。垃圾收集器通过引用计数或根搜索算法来识别可回收对象。复制算法高效但不压缩内存,符号碎片整理算法兼具效率和碎片减少。元数据区域的持久性可能会导致OOM(内存不足),因此必须小心管理。


HotSpotVM采用分代收集方式,新生代采用复制算法,老年代可以采用Mark-Compact算法。强引用会导致内存泄漏,而弱引用和弱引用则提供了内存回收的灵活性。串行收集器由于其简单和高效,在单线程场景中很常见。ParNew是多线程版本,适合Client模式下的下一代回收。用户可以通过调整线程数来优化性能。


服务器模式下的垃圾收集器

服务器模式下,ParallelScavenge等垃圾收集器注重程序吞吐量,SerialOld提供低暂停单线程清理,CMS和G1都有自己的特点。自己的重点:CMS追求低停顿时间但会影响CPU,而G1特点是灵活的堆区划分和无碎片管理,兼顾低停顿和高吞吐量。


内存管理和类加载

内存泄漏源于对短生命周期对象的长期引用。类加载过程包括加载、连接(验证、准备、分析)。和初始化。类的初始化仅在第一次使用时执行。常量池管理会影响类的初始化时间。类加载器遵循双亲委托机制来确保类型安全,而线程上下文加载器则在特定场景下提供灵活性。


了解线程上下文加载器,例如tthread().getContextClassLoader(),有助于解决标准库和自定义实现之间的兼容性问题。


总结

JVM的内存管理和垃圾收集机制是理解Java性能基石的关键。通过深入了解各个区域的特点和回收策略,以及类加载和上下文加载的原理,开发人员可以更有效地优化内存使用,保证应用程序的稳定运行。



二、java常见gc算法有哪些1:标记-清除标记-清除
流程:标记并清除可回收对象
缺点:标记和清除效率低,清除后会产生内存碎片
2:复制算法
过程:将内存分割成两个相等的块,将剩余的对象复制到另一块内存,清理已使用的内存
缺点:已使用的内存现在是原来的一半
演变:碎片内存被分割成一个Eden空间(80%)和两个Survivor空间(10%)的比例为8:1
每当使用Eden和Survivor时,存活的对象在回收时都会被复制到另一个空间。如果另一个Survivor空间不足,则替换旧代存储于
3:Mark-CompactMark-Compact
过程:将所有Survivor对象移动到一端并清除边界非内存
4:分代收集算法
处理:将堆分为新代和老代,根据你选择的区域特征改变收集算法,如果新生代很快消亡,则对老代使用复制算法,使用标记去除,或者使用标记排序
对于面试术语来说,这四个就足够了。