在Java虚拟机中,内存分配和回收是垃圾收集的核心内容。以下是一些常见的内存分配与回收策略:
内存分配策略:
- 对象优先在Eden区分配: 大部分新创建的对象都会被分配到Eden区。Eden区是年轻代的一部分,用于存放新创建的对象。
- 大对象直接进入老年代: 如果一个对象的大小超过了一定阈值(例如-XX:PretenureSizeThreshold参数设置的值),则会直接在老年代中分配空间。
-
长期存活的对象进入老年代: 对象经过多次垃圾回收仍然存活的,会逐渐晋升到老年代。可以通过设置
-XX:MaxTenuringThreshold
参数调整晋升的阈值。 - 动态对象年龄判定: 虚拟机会动态地检测每个对象的年龄,根据年龄晋升到不同的区域。这是为了避免一些“朝生夕死”的对象过早地晋升到老年代。
内存回收策略:
- Minor GC: 针对年轻代的垃圾回收称为Minor GC。它主要关注Eden区和Survivor区的回收,一般使用复制算法,将存活的对象复制到另一个Survivor区或老年代。
- Major GC(Full GC): 针对老年代的垃圾回收称为Major GC或Full GC。它涉及整个堆内存的回收,包括年轻代和老年代。Full GC的成本较高,会导致较长的停顿时间,因此尽量减少Full GC的发生。
-
并发与并行:
- 并行垃圾回收: 在垃圾回收时,多个线程并行地进行,提高垃圾回收的效率。例如,Parallel收集器主要用于年轻代的垃圾回收。
- 并发垃圾回收: 在垃圾回收过程中,垃圾收集线程和应用程序线程同时执行,以减小垃圾回收对应用程序的影响。例如,CMS收集器和G1收集器都属于并发垃圾回收器。
- 空间分配担保: 在进行Minor GC时,如果Survivor区无法容纳Eden区中存活的对象,或者老年代无法容纳年轻代中的存活对象,就会触发一次Full GC。为了避免这种情况,虚拟机会执行空间分配担保,提前晋升对象或触发一次Full GC。
- 永久代的垃圾回收: 在Java 8及之前的版本中,永久代(PermGen)主要用于存放类的元信息等,垃圾回收由Full GC负责。Java 8及以上版本移除了永久代,改为使用元空间(Metaspace),垃圾回收由Metaspace收集器负责。
这些策略的选择取决于应用程序的特性、硬件环境和性能要求。不同的垃圾收集器和调优参数可以根据具体需求来进行调整。
Was this helpful?
0 / 0