java经过这么多年的发展,已经成为相当成熟的技术,特别是在内存的动态分配与内存回收技术已经相当成熟,一切看起来都是如此的美妙和谐。那我们为什么还要了解GC和内存分配呢?这个我想不用多说大家都应该明白,正是java的这种自动化,这个对大多数程序员的黑盒,导致排查各种内存溢出和内存泄露问题,甚至成为系统达到高并发的瓶颈。
当我们的程序在运行的过程中,程序计数器、虚拟机栈、本地方法栈都随线程而生,随线程而死;栈中的栈帧随着方法的进入退出有条不紊的进栈出栈,每一帧的内存大小基本在类结构确定下来就已知了,虽然栈帧分配多少内存会被JIT编译器进行一些优化,但是大体我们可以认为是编译器可知的。因此这些区域不需要过多考虑内存的回收问题,因为方法结束,内存就自动回收了,我们关注的是java的堆的垃圾回收。
我们在分析堆的垃圾回收之前,首先要弄清除哪些对象是应该被回收的,也就是说对象的生死怎么判断。目前我所知道的就两种算法来判断对象的存活,第一种是引用计数算法第二种是根搜索算法。引用计数算法,就是每个对象有一个引用计数器,每当有一个地方引用了该对象,计数器就加1;当引用失效时,计数器就减1;只有计数器为0的对象才可以被回收。这种算法实现方式很简单,效率也很高。这个算法在python和微软的COM中广泛使用,但是java却没有使用该算法,原因是它很难解决对象之间的相互引用问题。根搜索算法(GC Roots Tracing)被使用在java和C#中,这个算法就是从根节点开始向下搜索,搜索的路径就被成为引用连,当一个对象到GC Roots没有任何引用链可达时,就表明该对象是可以回收的了。在java中,可以作为GC Roots的对象有:1.虚拟机栈中引用的对象2.方法区中类静态属性引用的对象3.方法区中常量引用的对象4.本地方法栈JNI中引用的对象。但是并不是所有在根搜素算法中不可达的对象,都会被回收。一个对象真正的要被回收,至少要经历两次标记过程。如果对象在进行根搜索后发现没有与GC Roots相连接的引用链,那么它会被第一次标记并且进行一次筛选,筛选的条件是对象是否有必要执行finalize()方法。当对象没有重写finalize()方法,或者该方法已经被虚拟机调用过,虚拟机都认为没有必要执行。没有必要执行finalize方法的对象将会被放到一个队列中,这时虚拟机会在队列中进行第二次标记,如果还是没有到GC Roots可达引用链,那么它就会被回收。
我们已经讲了堆中对象是否存活的判定方法,下面我们得说说例外一个运行时数据区域:方法区或者叫做永久代。在堆中,特别是新生代,一次YGC就可以回收70%-95%的空间,而永久代的效率就低多了,很多人甚至认为方法区是没有垃圾回收。永久代回收的东西分为两种:无用的常量和无用的类。常量的回收很简单,比如一个String类型的数据“YY”,如果没有任何用到这个常量,如果这个时候发生内存回收,并且需要回收,该常量就会被回收。但是无用的类的判断就比较复杂了,条件有如下三个:1.该类的对象全部都被回收,堆中没有任何实例。2.加载该类的ClassLoader已经被回收。3.该类对应的Class对象没有被引用,没有地方通过反射来访问该类。当且仅当这三个条件满足,这个对象才可以被回收,但是不一定被回收,跟对象不一样。可以通过-Xnoclassgc进行控制,还可以通过-verbose:class和-XX:+TraceClassLoading、-XX:+TraceClassUnLoading查看类的加载和卸载信息。-verbose:class和-XX:+TraceClassLoading可以在product版的虚拟机中使用,但是-XX:TraceClassLoading参数需要fastdebug版的虚拟机支持。说了这多,其实在java的发展规划中,方法区也许会被Native Memory所代替。
分享到:
相关推荐
jvm-full-gc调优-jvm-full-gc
用于测试jvm gc调优-share-jvm-gc
深入java虚拟机光盘资源jvm-gc-logs-analyzer 这个项目是一个 Java 虚拟机和垃圾收集器日志分析器。 它专用于 JVM 11 及更高版本(JVM 8 支持正在开发中)。 日志必须采用适当的格式和适当的装饰器,检查最后部分的...
1、java虚拟机的基本介绍。 2、字节码的执行 3、常用的jvm参数配置 4、算法和种类 5、gc参数配置 6、类加载器 7、性能监控工具 8、jvm堆栈分析
JVM初探- 内存分配、GC原理与垃圾收集器,从从提上讲解了jvm中GC的原理、基本的算法和针对不同内存区使用的算法,同时,详细的讲解了当前主要使用的垃圾收集器
jvm-int-gc-基准 JVM 内部 - 垃圾收集基准
jvm性能调优-垃圾收集器parnew&CMS底层三色标记算-performance-gc-parnew-cms
【IT十八掌徐培成】Java基础第26天-03.JVM结构-finalize-gc.zip
JVM_GC_-调优总结
本文档可以作为学习JVM GC的工具书所使用,对于想深入学习JVM GC原理的同学,这一本书就足够了。因为本文档是作者花费数月时间,查阅GC相关的国内外众多资料并加以思路清晰的条目化而形成。因为篇幅所限,可能有部分...
对gc日志进行统计分析,使用命令:java -jar gcviewer-1.3x.jar gc.log summary.csv [chart.png] [-t PLAIN|CSV|CSV_TS|SIMPLE|SUMMARY]
jvmgc过程介绍(jpg)
今天我们讲讲JDK9中的JVM GC调优参数,JDK9中JVM的参数总共有2142个,其中正式的参数有659个。好像比JDK8中的参数要少一点。 为了方便大家的参考,特意将JDK9中的GC参数总结成了一张PDF,这个PDF比之前总结的JDK8的...
JVM GC垃圾回收.pdf
com-sun-tools-visualvm-modules-visualgc-2.1.2 java 虚拟机jvm内存管理软件visualVM的插件visualGC,适合jdk1.7和jdk1.8。使用方法:打开visualVM,工具->插件->已下载->添加插件,定位到本地下载的visualGC位置,...
The-Pauseless-GC-Algorithm-Azul 无暂停垃圾手机算法,来源于业内著名的JVM开发商 Azul
目前,Java是最为流行的编程语言之一,它的基础平台就是JVM。除了Java,如JRuby、Scala、Clojure等语言也运行在JVM平台。熟悉和掌握JVM平台有着重要的实用价值和意义。 在本课程中个,将详细介绍JVM的基本原理、...
JVM与GC调优课程视频 〖课程介绍〗: JVM与GC调优课程视频 〖课程目录〗: 1.笔记/ ├── 第1篇-字节码篇.png?x-oss-process=style/pnp8 ├── 第2篇-类的加载篇.png?x-oss-process=style/pnp8 ├── 第3篇-运行时...
resin jvm性能优化 一、优化配置 修改 conf/resin.conf 文章中的 JVM参数 <jvm-arg>-Xms512m</jvm-arg> <jvm-arg>-Xss128k</jvm-arg> <jvm-arg>-Xmn184m</jvm-arg> ...<jvm-arg>-Xloggc:gc.log</jvm-arg>