概述
JAVA是我们现在最常用的开发语言,而他的垃圾回收机制(Garbage Collection)的重要作用不言而喻,以下简称GC,所以了解GC至关重要,现本人对于GC机制以前的理解和现在的理解记录整理一下,供大家参考和指正。
说起GC机制,大部分人都把这项技术当做JAVA语言的伴生物。事实上,GC的历史比JAVA久远的多,比如:1960年诞生于MIT的Lisp是第一门真正使用内存动态分配和垃圾收集技术的语言,当然本文只讲解JAVA的GC机制。废话到此为止。
除了基础知识的讲解还有本人之前的测试数据和测试日志,JDK的版本是:JDK1.8.0_131。
JVM简介
在JAVA程序中,GC运行在JVM虚拟机中的,所以有必要了解JVM的基础知识;
所有的开发人员在开发运行JAVA程序的时候,都会有这样的困惑,JVM虚拟机是JAVA的核心竞争力,他们的内存结构是什么样的呢?见下图,当然也是本人借鉴网上的:
JVM内存结构主要有三大块:堆内存、方法区和栈。而堆内存就是JVM中最大的一块由年轻代和老年代组成,而年轻代又分为三部分,Eden空间、From Survivor空间、To Survivor空间,默认情况下年轻代按照8:1:1的比列来分配。
方法区存储类信息、常量、静态变量等数据,是线程共享的区域,为与Java堆区分,方法区还有一个别名Non-Heap(非堆);栈又分为java虚拟机栈和本地方法栈主要用于方法的执行。
在通过一张图来了解如何通过参数来控制各区域的内存大小:
控制参数
-Xms设置堆的最小空间大小。
-Xmx设置堆的最大空间大小。
-XX:NewSize设置新生代最小空间大小。
-XX:MaxNewSize设置新生代最大空间大小。
-XX:PermSize设置永久代最小空间大小。
-XX:MaxPermSize设置永久代最大空间大小。
-Xss设置每个线程的堆栈大小。
没有直接设置老年代的参数,但是可以设置堆空间大小和新生代空间大小两个参数来间接控制。
老年代空间大小=堆空间大小-年轻代大空间大小。
从更高的一个维度再次来看JVM和系统调用之间的关系:
如果按照线程是否共享来分类的话,如下图所示:
方法区和对是所有线程共享的内存区域;而java栈、本地方法栈和程序员计数器是运行是线程私有的内存区域。
下面我们详细介绍每个区域的作用:
JAVA堆HE