Java较C而言,最大的区别在于内存管理。JVM设有无用内存空间自动回收复用机制,也就是我们所说的GC。

之前说过,栈是为线程、为函数的执行分配内存的地方,用完即“销毁”,这里留待以后做深入探讨;堆是为对象和数组分配内存的地方,有些对象可能会伴随着程序运行的完整生命周期,但大部分对象都是朝生夕死的,如何判断对象是否有必要“占坑”呢?首先我们要来说一下判别方法:Java中对象的活性判别主要有两种,引用计数法和可达性分析法。

引用计数法:为每个对象设立一个计数器,对象每被引用一次,计数器加一,当引用失效的时候,计数器减一。原理简单易懂,但存在一个致命问题,无法处理循环引用问题。如果A.son = B; B.son = A;A和B除此之外再无其他引用,按需求A和B应该被回收掉,但引用计数法却无法识别这种引用。

可达性分析法:JVM列出一些称之为GC Roots的对象,把它们作为活对象的源头,如果顺着它们的引用能找到的对象,一律认为是活着的。那么哪些对象可以当作GC Roots呢?能作为GC Roots的对象,一定是程序目前运行中的正在使用的对象。JVM规定了以下四类:

1、栈里面的本地变量表中,引用类型所指向的对象;

2、本地方法栈中Native方法所引用的对象;

3、方法区中常量所指向的对象;

4、方法区中类的静态属性所指向的对象


针对上述两种方法,都存在一个共有名词:引用!如果只存在一种引用,非黑即白,那么Java也太不智能了。所以,Java中把引用分为四个等级,有强有弱,依次分为:

强引用:我们最常见的引用类型,类似于User user = new User();强引用是真的引用!

软引用:当JVM申请不到额外内存了,快到内存溢出时,会把软引用的对象处理掉腾出空间;SoftReference类

弱引用:通过弱引用关联的对象只能活到下次GC之前;WeakReference类

虚引用:这种引用连最基本的调用都无法实现,仅仅用来为对象发送GC通知。PhantomReference类

finalize方法

对于那些不可达的对象,也不是不给它们申辩机会的。当JVM发现程序不可达后,会对这个对象进行一次标记,此时对象如果重写了finalize方法,JVM会把它扔进F_Queue的队列之中,并在之后创建一个低优先级的Finalizer线程去触发这个对象的finalize方法。JVM 会对队列中的对象进行第二次标记,如果在执行方法之后,这个对象成功与活着的对象产生引用关联,那么他将被移除这个队列,对象成功拯救了自己。如果没有重写finalize方法或者没能取得引用关联,下次GC的时候它就真的会被回收掉了。

但是不建议使用这个方法来干预JVM的GC过程,因为代价高昂,不确定性大,finalize方法能做的事情在try finally中都可以做得更好更及时。

方法区回收

栈、堆、方法区是三个占用内存最大的地方,其中对堆区进行GC最高效,对方法区GC情况就很不乐观了。方法区在一些JVM中又叫永久代,他们不会对方法区进行GC操作。

方法区是用来存放类信息的地方,这里可以把常量池中无用常量和无用类回收掉。

常量回收:如果一个字面量没有对象引用它,如“abc”,那么就可以把它清理出常量池了。

类回收:当一个类1、所有实例都被已经回收掉 2加载该类的classLoader已经被回收; 3、该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法,满足这三个条件的类就可以清理掉了,条件很苛刻,但是满足这三点的类也不是说一定会被清理,而是通过参数来控制。如果你的程序大量使用了动态生成class(反射,动态代理,动态生成jsp等),以及大量自定义classLoader(OSGi)的场景,可以设置类卸载的功能来防止方法区溢出。

JVM之GC(一)的更多相关文章

  1. JVM的GC概述

    JVM的GC概述 GC即垃圾回收,是指jvm用于释放那些不再使用的对象所占用的内存.在充分理解了垃圾收集算法和执行过程后,才能有效的优化它的性能. 有些垃圾收集专用于特殊的应用程序.比如,实时应用程序 ...

  2. Linux使用jstat命令查看jvm的GC情况

    Linux使用jstat命令查看jvm的GC情况 http://www.open-open.com/lib/view/open1390916852007.html http://www.aiuxian ...

  3. poptest老李谈jvm的GC

    poptest老李谈jvm的GC   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:90882 ...

  4. Linux使用jstat命令查看jvm的GC情况(转)

    B. jstack jstack主要用来查看某个Java进程内的线程堆栈信息.语法格式如下: 1 jstack [option] pid 2 jstack [option] executable co ...

  5. jvm的GC日志分析 [转]

      jvm的GC日志分析 标签: jvm内存javagc 2015-06-22 16:37 1566人阅读 评论(1) 收藏 举报  分类: Java(4)  JVM的GC日志的主要参数包括如下几个: ...

  6. JVM 的GC算法和垃圾收集器

    1.标记清除算法 黑色部分代表可回收对象,灰色部分代表存活对象,绿色部分代表未使用的.最基础的收集算法就是标记清除算法如同他名字一样,算法分为"标记"和"清除" ...

  7. JVM&G1 GC 学习笔记(一)

    在入门学习JVM的过程中,我们需要先了解关于JVM的知识中有哪些关键词或关键术语,今天在看完书后我想记录下来. Xms64mb    虚拟机初始化时设置内存大小为64mb Xmx256mb  设定虚拟 ...

  8. 深入理解JVM+G1+GC.pdf (中文版带书签)

    目录 序 VII前言 IX 第1章 JVM & GC基础知识 11.1 引言 21.2 基本术语 31.2.1 Java相关术语 41.2.2 JVM/GC通用术语 241.2.3 G1涉及术 ...

  9. JVM之GC(二)

    昨天总结了GC之前要做的事情,今天介绍一下主流的GC算法. 先介绍一下几个名词: Stop The World(STW):JVM进行GC的时候总不能一边清理垃圾一边制造垃圾把,那么垃圾鉴定的准确性根本 ...

随机推荐

  1. poj 2442 Sequence (Priority Queue)

    2442 -- Sequence 真郁闷,明明方法是对的,为什么我的代码老是那么的慢._(:з」∠)_ 这题要想考虑两列的情况,然后逐列拓展. 代码如下: #include <cstdio> ...

  2. [C#] 如何把void*转换为byte[]

    一般来说,C#库的对外接口应该提供byte[]这样比较容易用的接口,而不应该提供裸的void* 但是有些库确实是这么封装的.那么就有一个如何转换的问题.MSDN推荐的转换方式是使用UnmanagedM ...

  3. 自然语言处理课程(二):Jieba分词的原理及实例操作

    上节课,我们学习了自然语言处理课程(一):自然语言处理在网文改编市场的应用,了解了相关的基础理论.接下来,我们将要了解一些具体的.可操作的技术方法. 作为小说爱好者的你,是否有设想过通过一些计算机工具 ...

  4. mac常用快捷键,Mac文件重命名快捷键,Mac OS快速访问系统根目录, MacOS 10.11重要数据的存储位置大全

    command+r,相当于F5,刷新页面 command+F5,启动voiceover command+q 关闭当前程序 在Finder中command+/ 打开底部状态栏,可以查看剩余磁盘空间大小 ...

  5. 2019-1-16-git-subtree-pull-错误-Working-tree-has-modifications

    title author date CreateTime categories git subtree pull 错误 Working tree has modifications lindexi 2 ...

  6. 2018-2-13-C#-枚举转字符串

    title author date CreateTime categories C# 枚举转字符串 lindexi 2018-2-13 17:23:3 +0800 2018-2-13 17:23:3 ...

  7. 2018-8-10-win10-uwp-调试软件启动

    title author date CreateTime categories win10 uwp 调试软件启动 lindexi 2018-08-10 19:16:51 +0800 2018-03-0 ...

  8. Hex编码

    编码原理 Hex编码就是把一个8位的字节数据用两个十六进制数展示出来,编码时,将8位二进制码重新分组成两个4位的字节,其中一个字节的低4位是原字节的高四位,另一个字节的低4位是原数据的低4位,高4位都 ...

  9. 【踩坑记录】vue单个组件内<style lang="stylus" type="text/stylus" scoped>部分渲染失效

    vue组件化应用,近期写的单个组件里有一个的渲染部分样式渲染不上去 因为同结构的其他组件均没有问题,所以排除是.vue文件结构的问题,应该是<style>内部的问题 <style l ...

  10. 2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树)

    2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树) 传送门:https://nanti.jisuanke.com/t/41296 题意: 给一个数列A 问在数列A中有多 ...