GC

1.Java 语言中一个显著的特点就是引入了垃圾回收机制,它使得 Java 程序员在编写程序的时候不再需要考虑内存管理。对于 GC 来说,当程序员创建对象时,GC 就开始监控这个对象的地址、大小 以及使用情况。通常,GC 采用有向图的方式记录和管理堆(heap)中的所有对象。 通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的"。当 GC 确定一些对象为"不可达"时,GC 就有责任回收这些内存空间;

手动执行代码:System.gc() 或 Runtime.getRuntime().gc() ;

2.Java堆内存结构: 

Java将堆内存分为3大部分:新生代、老年代和永久代,其中新生代又进一步划分为Eden、S0、S1(Survivor)三个区,结构如下图所示:


我们在程序中new出来的对象一般情况下都会在新生代里的Eden区里面分配空间,如果存活时间足够长将会进入Survivor区,进而如果存活时间再长,还会被提升分配到老年代里面。持久代里面存放的是Class类元数据、方法描述等。

S0和S1是两个大小相等的区域,分配内存空间只会在其中某一个进行,另外一个空间是用来辅助进行新生代进行垃圾回收的,因为新生代的垃圾回收策略基于复制算法,其思想是将Eden区及两个Survivor中的某个区,如S0区里面需要存活的对象复制到另外一个空的Survivor区,如S1区,然后就可以回收Eden和S0区域里面的死亡对象。下一次回收就对调S0和S1两个区的角色,S1用来存放存活对象而S0用来辅助回收垃圾,如此循环利用。

有些文章并不将永久代纳入Java堆内存。其实永久代就是我们所说的方法区,而方法区经常被称为Non-Heap(非堆)。仅仅在HotSpot虚拟机的实现中才将GC分代收集扩展至方法区,或者说使用永久代来实现方法区,对于其他的虚拟机是不存在永久代这个概念的。 

并非所有的对象创建都会在Eden区中分配内存空间。对于Serial和ParNew垃圾收集器,通过指定-XX:PretenureSizeThreshold={size}来设置超过这个阈值大小的对象直接进入老年代。

2. 分代回收算法

我们一般讨论的垃圾回收主要针对Java堆内存中的新生代和老年代,也正因为新生代和老年代结构上的不同,所以产生了分代回收算法,即新生代的垃圾回收和老年代的垃圾回收采用的是不同的回收算法。针对新生代,主要采用复制算法,而针对老年代,通常采用标记-清除算法或者标记-整理算法来进行回收。


更多内容点击此处(原文):https://blog.csdn.net/d6619309/article/details/53358250

你可能感兴趣的:(GC)