范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

Java垃圾回收概述

  1. 什么是垃圾
  在提到什么是垃圾之前,我们先看下面一张图
  从上图我们可以很明确的知道,Java 和 C++语言的区别,就在于垃圾收集技术和内存动态分配上,C语言没有垃圾收集技术,需要我们手动的收集。垃圾收集,不是Java语言的伴生产物。早在1960年,第一门开始使用内存动态分配和垃圾收集技术的Lisp语言诞生。 关于垃圾收集有三个经典问题:哪些内存需要回收?什么时候回收?如何回收?
  垃圾收集机制是Java的招牌能力,极大地提高了开发效率。如今,垃圾收集几乎成为现代语言的标配,即使经过如此长时间的发展,Java的垃圾收集机制仍然在不断的演进中,不同大小的设备、不同特征的应用场景,对垃圾收集提出了新的挑战。1.1 什么是垃圾?
  垃圾是指在运行程序中没有任何指针指向的对象,这个对象就是需要被回收的垃圾。如果不及时对内存中的垃圾进行清理,那么,这些垃圾对象所占的内存空间会一直保留到应用程序的结束,被保留的空间无法被其它对象使用,甚至可能导致内存溢出。2. 为什么需要GC
  对于高级语言来说,一个基本认知是如果不进行垃圾回收,内存迟早都会被消耗完,因为不断地分配内存空间而不进行回收,就好像不停地生产生活垃圾而从来不打扫一样。
  除了释放没用的对象,垃圾回收也可以清除内存里的记录碎片。碎片整理将所占用的堆内存移到堆的一端,以便JVM将整理出的内存分配给新的对象。
  随着应用程序所应付的业务越来越庞大、复杂,用户越来越多,没有GC就不能保证应用程序的正常进行。而经常造成STW的GC又跟不上实际的需求,所以才会不断地尝试对GC进行优化。3. 早期垃圾回收
  在早期的C/C++时代,垃圾回收基本上是手工进行的。开发人员可以使用new关键字进行内存申请,并使用delete关键字进行内存释放。这种方式可以灵活控制内存释放的时间,但是会给开发人员带来频繁申请和释放内存的管理负担。倘若有一处内存区间由于程序员编码的问题忘记被回收,那么就会产生内存泄漏,垃圾对象永远无法被清除,随着系统运行时间的不断增长,垃圾对象所耗内存可能持续上升,直到出现内存溢出并造成应用程序崩溃。4. Java垃圾回收机制4.1 优点
  自动内存管理,无需开发人员手动参与内存的分配与回收,这样降低内存泄漏和内存溢出的风险。如果没有自动垃圾回收机制,java也会和c语音一样,各种悬垂指针,野指针,泄露问题让你头疼不已。自动内存管理机制,将程序员从繁重的内存管理中释放出来,可以更专心地专注于业务开发4.2 缺点
  对于Java开发人员而言,自动内存管理就像是一个黑匣子,如果过度依赖于"自动",那么这将会是一场灾难,最严重的就会弱化Java开发人员在程序出现内存溢出时定位问题和解决问题的能力。
  此时,了解JVM的自动内存分配和内存回收原理就显得非常重要,只有在真正了解JVM是如何管理内存后,我们才能够在遇见outofMemoryError时,快速地根据错误异常日志定位问题和解决问题。
  当需要排查各种内存溢出、内存泄漏问题时,当垃圾收集成为系统达到更高并发量的瓶颈时,我们就必须对这些"自动化"的技术实施必要的监控和调节。4.3 GC主要关注的区域
  GC主要关注于 方法区 和堆中的垃圾收集
  垃圾收集器可以对年轻代回收,也可以对老年代回收,甚至是全栈和方法区的回收
  其中,Java堆是垃圾收集器的工作重点
  从次数上讲:频繁收集Young区较少收集Old区基本不收集Perm区(元空间)5. System.gc()的理解
  在默认情况下,通过system.gc()者Runtime.getRuntime().gc() 的调用,会显式触发FullGC,同时对老年代和新生代进行回收,尝试释放被丢弃对象占用的内存。
  然而system.gc() )调用附带一个免责声明,无法保证对垃圾收集器的调用。(不能确保立即生效)
  JVM实现者可以通过system.gc() 调用来决定JVM的GC行为。而一般情况下,垃圾回收应该是自动进行的,无须手动触发,否则就太过于麻烦了。在一些特殊情况下,如我们正在编写一个性能基准,我们可以在运行之间调用System.gc()。6. 内存溢出
  内存溢出相对于内存泄漏来说,尽管更容易被理解,但是同样的,内存溢出也是引发程序崩溃的罪魁祸首之一。
  由于GC一直在发展,所有一般情况下,除非应用程序占用的内存增长速度非常快,造成垃圾回收已经跟不上内存消耗的速度,否则不太容易出现OOM的情况。
  大多数情况下,GC会进行各种年龄段的垃圾回收,实在不行了就放大招,来一次独占式的FullGC操作,这时候会回收大量的内存,供应用程序继续使用。
  首先说没有空闲内存的情况:说明Java虚拟机的堆内存不够。原因有二:Java虚拟机的堆内存设置不够。
  比如:可能存在内存泄漏问题;也很有可能就是堆的大小不合理,比如我们要处理比较可观的数据量,但是没有显式指定JVM堆大小或者指定数值偏小。我们可以通过参数-Xms 、-Xmx来调整。代码中创建了大量大对象,并且长时间不能被垃圾收集器收集(存在被引用)
  在抛出OutofMemoryError之前,通常垃圾收集器会被触发,尽其所能去清理出空间。当然,也不是在任何情况下垃圾收集器都会被触发的。比如,我们去分配一个超大对象,类似一个超大数组超过堆的最大值,JVM可以判断出垃圾收集并不能解决这个问题,所以直接抛出OutofMemoryError。7. 内存泄漏
  也称作"存储渗漏"。严格来说,只有对象不会再被程序用到了,但是GC又不能回收他们的情况,才叫内存泄漏。
  但实际情况很多时候一些不太好的实践(或疏忽)会导致对象的生命周期变得很长甚至导致00M,也可以叫做宽泛意义上的"内存泄漏"。
  尽管内存泄漏并不会立刻引起程序崩溃,但是一旦发生内存泄漏,程序中的可用内存就会被逐步蚕食,直至耗尽所有内存,最终出现outofMemory异常,导致程序崩溃。7.1 举例单例模式
  单例的生命周期和应用程序是一样长的,所以单例程序中,如果持有对外部对象的引用的话,那么这个外部对象是不能被回收的,则会导致内存泄漏的产生。
  一些提供close的资源未关闭导致内存泄漏
  数据库连接(dataSourse.getConnection() ),网络连接(socket)和io连接必须手动close,否则是不能被回收的。
  8. 对象已死?
  堆里几乎存放着java中所有的实例对象,在对堆进行回收前,第一件事情就是要确定这些对象有哪些还 "存活" 着 ?哪些已经 "死去" (不可能再被任何途径使用的对象)。8.1 引用计数算法
  给对象中增加一个引用计数器,每当一个地方引用它时,计数器值就加1;当引用失效,计数器值就建1;计算器为0的对象就是不可能再被使用的。
  引用计数算法的实现简单,判断效率也很高,但是它很难解决对象之间的相互循环引用的问题。所以Java没有选用引用计数算法来管理内存。8.2 根搜索算法
  通过一系列的称为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索的路径称为引用链,当一个对象到"GC Roots"没有任何引用链相连的话,也就是GC Roots到这个对象不可达时,证明此对象已经不可用,可以被回收了。
  可作为GC roots的对象的包括下面几种:栈中的对象引用、 方法区中常量的引用、 方法区中静态对象的引用、 本地方法区中native对象的引用
  9. Stop The World
  stop-the-world,简称STW,指的是GC事件发生过程中,会产生应用程序的停顿。停顿产生时整个应用程序线程都会被暂停,没有任何响应,有点像卡死的感觉,这个停顿称为STW。
  可达性分析算法中枚举根节点(GC Roots)会导致所有Java执行线程停顿。
  被STW中断的应用程序线程会在完成GC之后恢复,频繁中断会让用户感觉像是网速不快造成电影卡带一样,所以我们需要减少STW的发生。
  STW事件和采用哪款GC垃圾回收器无关所有的GC都有这个事件。哪怕是G1也不能完全避免Stop-the-world情况发生,只能说垃圾回收器越来越优秀,回收效率越来越高,尽可能地缩短了暂停时间。
  STW是JVM在后台自动发起和自动完成的。在用户不可见的情况下,把用户正常的工作线程全部停掉。开发中不要用system.gc() 会导致stop-the-world的发生。10. 安全点与安全区域
  通过上文我们知道 HotSpot 虚拟机采取的是可达性分析算法。即通过 GC Roots 枚举判定待回收的对象。那么,首先要找到哪些是 GC Roots。有两种查找 GC Roots 的方法:一种是遍历方法区和栈区查找(保守式 GC)。一种是通过 OopMap 数据结构来记录 GC Roots 的位置(准确式 GC)。
  保守式 GC 的成本太高。准确式 GC 的优点就是能够让虚拟机快速定位到 GC Roots。对应 OopMap 的位置即可作为一个安全点(Safe Point)。在执行 GC 操作时,所有的工作线程必须停顿,这就是所谓的"Stop-The-World"。
  为什么呢?
  因为可达性分析算法必须是在一个确保一致性的内存快照中进行。如果在分析的过程中对象引用关系还在不断变化,分析结果的准确性就不能保证。安全点意味着在这个点时,所有工作线程的状态是确定的,JVM 就可以安全地执行 GC 。10.1 安全点
  程序执行时并非在所有地方都能停顿下来开始GC,只有在特定的位置才能停顿下来开始GC,这些位置称为"安全点(Safepoint)"。
  Safe Point的选择很重要,如果太少可能导致GC等待的时间太长,如果太频繁可能导致运行时的性能问题。大部分指令的执行时间都非常短暂,通常会根据"是否具有让程序长时间执行的特征"为标准。
  比如:选择一些执行时间较长的指令作为Safe Point,如方法调用、循环跳转和异常跳转等。
  如何在gc发生时,检查所有线程都跑到最近的安全点停顿下来呢?抢先式中断:(目前没有虚拟机采用)首先中断所有线程。如果还有线程不在安全点,就恢复线程,让线程跑到安全点。主动式中断:设置一个中断标志,各个线程运行到Safe Point的时候主动轮询这个标志,如果中断标志为真,则将自己进行中断挂起。(有轮询的机制)
  注意:程序运行到安全点,不是一定要进行垃圾回收。而是在这些点上进行垃圾回收,较为安全。所以叫做安全点。10.2 安全区域
  Safepoint 机制保证了程序执行时,在不太长的时间内就会遇到可进入GC的Safepoint。但是,程序"不执行"的时候呢?例如线程处于sleep-状态或Blocked 状态,这时候线程无法响应JVM的中断请求,"走"到安全点去中断挂起,JVM也不太可能等待线程被唤醒。对于这种情况,就需要安全区域(Safe Region)来解决。
  安全区域是指在一段代码片段中,对象的引用关系不会发生变化,在这个区域中的任何位置开始Gc都是安全的。我们也可以把Safe Region看做是被扩展了的Safepoint。
  执行流程:当线程运行到Safe Region的代码时,首先标识已经进入了Safe Relgion,如果这段时间内发生GC,JVM会忽略标识为Safe Region状态的线程当线程即将离开Safe Region时,会检查JVM是否已经完成GC,如果完成了,则继续运行,否则线程必须等待直到收到可以安全离开Safe Region的信号为止。
  11. 强引用、软引用、虚引用、弱引用11.1 强引用
  当内存不足,jvm开始垃圾回收,对于强引用的对象,就算是出现了OOM也不会对该对象进行回收。这也是Java中最常见的普通对象的引用,只要还有强引用指向这个对象,就不会被垃圾回收。
  当这个对象没有了其他的引用关系,只要是超过了引用的作用域,或者显示的将强引用赋值为null,一般就可以进行垃圾回收了。11.2 软引用
  软引用是相对强引用弱化了一些的引用,对于软引用的对象来说:当内存充足时,它不会被回收。当内存不足时。会被回收。
  通常用在对内存敏感的程序中,就像高速缓存。11.3 弱引用
  发现即回收
  弱引用也是用来描述那些非必需对象,被弱引用关联的对象只能生存到下一次垃圾收集发生为止。在系统GC时,只要发现弱引用,不管系统堆空间使用是否充足,都会回收掉只被弱引用关联的对象。但是,由于垃圾回收器的线程通常优先级很低,因此,并不一定能很快地发现持有弱引用的对象。在这种情况下,弱引用对象可以存在较长的时间。
  弱引用和软引用一样,在构造弱引用时,也可以指定一个引用队列,当弱引用对象被回收时,就会加入指定的引用队列,通过这个队列可以跟踪对象的回收情况。
  软引用、弱引用都非常适合来保存那些可有可无的缓存数据。如果这么做,当系统内存不足时,这些缓存数据会被回收,不会导致内存溢出。而当内存资源充足时,这些缓存数据又可以存在相当长的时间,从而起到加速系统的作用。
  在JDK1.2版之后提供了WeakReference类来实现弱引用
  // 声明强引用 Object obj = new Object(); // 创建一个弱引用 WeakReference sf = new WeakReference<>(obj); obj = null; //销毁强引用,这是必须的,不然会存在强引用和弱引用
  弱引用对象与软引用对象的最大不同就在于,当GC在进行回收时,需要通过算法检查是否回收软引用对象,而对于弱引用对象,GC总是进行回收。弱引用对象更容易、更快被GC回收。
  开发中使用过WeakHashMap的场景?
  WeakHashMap用来存储图片信息,可以在内存不足的时候,及时回收,避免了OOM11.4 虚引用
  也称为"幽灵引用"或者"幻影引用",是所有引用类型中最弱的一个一个对象是否有虚引用的存在,完全不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它和没有引用几乎是一样的,随时都可能被垃圾回收器回收。它不能单独使用,也无法通过虚引用来获取被引用的对象。当试图通过虚引用的get()方法取得对象时,总是null。为一个对象设置虚引用关联的唯一目的在于跟踪垃圾回收过程。比如:能在这个对象被收集器回收时收到一个系统通知。
  虚引用必须和引用队列一起使用。虚引用在创建时必须提供一个引用队列作为参数。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象后,将这个虚引用加入引用队列,以通知应用程序对象的回收情况。由于虚引用可以跟踪对象的回收时间,因此,也可以将一些资源释放操作放置在虚引用中执行和记录。
  在JDK1.2版之后提供了PhantomReference类来实现虚引用。// 声明强引用 Object obj = new Object(); // 声明引用队列 ReferenceQueue phantomQueue = new ReferenceQueue(); // 声明虚引用(还需要传入引用队列) PhantomReference sf = new PhantomReference<>(obj, phantomQueue); obj = null;
来自世界各地的四位鼓舞人心的电子商务女性尽管有研究表明,女性比例较高的企业利润更高,女性更擅长管理,但在财富500强企业中,只有4。2的企业由女性执掌。这种不平等主要是由对女性企业家的偏见造成的,尤其是在创业生态系统中。百年巨头爆雷!这一世界500强企业,濒临被收购!发生了什么?来源央视财经瑞士信贷成立于1856年,有着一百六十多年的历史。2001年时,瑞信曾高居财富杂志世界500强企业排行榜第38位。如今却深陷泥潭,濒临被收购许多人不禁会发问瑞信这几年到女人上了年纪,要懂得断舍离,旧裙子记住3扔3不扔,优雅时髦随着时代的发展,现在的人们思想观念越来越先进,尤其是在断舍离这件事情上,很多人也都有了共鸣,其实衣服和其他物品并不是越多越好,尤其是在这个物质充盈的时代,有时候断舍离反倒是让我们回女人的气质怎么培养起来让你更优雅自信女人的气质是她们与生俱来的天赋,但这并不意味着它不可培养。气质是由多种因素组成的,包括外表态度社交技巧和思维方式等。无论你现在的气质如何,你都可以通过一些简单的技巧来提升它,从而成混官场的秘诀!脏不粘身的智慧!夜读资治通鉴最近,无论是公家单位还是私企,又刮起了一阵反腐倡廉的旋风。看着那些违法违纪的,领导干部的所作所为,让人心中愤慨难休。在官场上,要怎样做才能守住清廉底线,不被别有用心者拉下水,跌入万国企改革中特估创建世界一流企业航天系数字中国电科系国企改革新一轮国企改革已经蓄势待发,未来的三年国企改革和过去三年会有本质的区别,之前的重视大,现在是重视质量,细分行业的国产代替和战略新兴产业会是国企改革的重点。未来推动央企集团及让北宋头痛不已的契丹,是现在的哪个民族?说出来你或许不信中原农耕文明与北方游牧民族的撞击,贯穿了整部中国古代史。秦汉马踏匈奴过燕然的豪气,南北朝西晋汉关尸野岸的惨烈,隋唐不破楼兰誓不还的悲壮,满清痛说扬州十日围的激愤。无一不在诉说着中华商王朝兴亡史权力更迭的历史商朝是中国历史上第一个有文献可考,并为考古学和甲骨文所证实的都城,是有文字可查的第一个王朝。据殷都遗址和出土的文物,推测出商王朝时代中华文明已经发展到相当成熟的阶段。本篇文章我们一为什么有人宁愿买Mate50,也不等华为P60?三个原因看破且说破基本上只要对手机行业有所关注的人,都已经知道了华为公司将在3月23号发布华为P60系列旗舰的消息,因为这是华为公司旗下新一代的重磅旗舰,本来华为手机在国内的人气就高,至于它旗下的重三十年了,历史的总结德生收音机中设计最好的收音机,没有之一原创yyds在我看来,非CR1000莫属,理由如下1界面清楚。按键很少,操作简单,位置合理,例如那个电源开关,这个方向的按钮在力学上是最合理的,垂直按电源是最方便的,水平方向会把收现在大家都在说数字化,数字化到底是什么?数字化就是把真实世界抽象成数字的过程。具体来说就是将我们所生活的真实世界和虚拟的数字表达链接起来,从而将已有信息转换成可分析的数据。比如改变了所有人生活的移动互联网,就是一个庞大的
为啥美国胖子较多,但脑梗率却较低?医生1多1少可借鉴学习导语在我们大家的印象当中,脑梗这种问题大多数会出现中老年人的身上都是老人,还存在着高血压肥胖高血脂等问题,那么出现脑梗的风险相对而言也会更高。著名医学杂志NEJM上面发布的一则报告民间故事刘伯温预测虎年,贫者一万留一千,富者一万留二三在古代,有这样一群人,他们能够在小小的方寸之间,就预知天下大事。而这一类的人也被叫做谋士,是想要谋划天下的帝王们最想要的人才。而在这一类人中,最为出名的就是三国时期助力刘备谋划天下母乳的成分1。母乳的营养成分母乳的营养成分在产后不同时期有所不同,初乳指产前及产后7天内的乳汁,产后714天为过渡乳,15天以后为成熟期乳。初乳比成熟乳中的蛋白质含量高而脂肪与乳糖较低,适合于新生儿消化特点。多喝水毁了肾,粗茶淡饭伤透肝?4个坑人的养生建议,越养病越多张大婶今年56岁,是一名养生爱好者。自从她55岁退休之后,还加入了一个养生群,里面全是和她一样热爱养生的人。在张大婶的养生圈子里流行着一句话,叫做没事多喝水,粗茶淡饭更健康。她也认出自排球荒漠,17岁高中生帮助上海女排闯进决赛,中国女排的希望山西,在我们的印象中,基本是一片排球的荒漠。2023年1月3日,上海女排在中国女排超级联赛第二场半决赛中,30淘汰深圳女排,闯进决赛。这场胜利,却不经意地,打上了山西的烙印。因为,独爱前中超球员!土媒曝胡尔克即将加盟,前妻侄女刚为他添女头条创作挑战赛北京时间1月3日,土耳其媒体表示,阿达姆代米尔体育正在和米内罗竞技队谈判,期望能够在转会期开始后签下前海港前锋胡尔克。去年,他们签约了俄罗斯中锋久巴,但很快与其解约。名记曝乐福愿降薪留在骑士,骑士希望乐福能在克利夫兰终老据名记theathleitc报道,凯文乐福与骑士具有意在2023年完成续约。乐福此前表示自己不在乎薪资多少,只想在克利夫兰打球,故乐福也对骑士管理层提出的降薪留队不会太感冒。乐福此散文丨杨守知一个村庄的南北东西一个村庄的南北东西文丨杨守知南在故乡的南山上,我见到了远房的五婶。那个年过八旬的罗圈腿的矮女人,在五叔坟前无声哭泣。那是今年的中元节,多雨的夏季即将结束,墓地的荆棵密不透风。五婶捏与2022最友好的告别方式欢迎你,202313回溯两大业务大家好我叫郭泽君是一名旅行摄影人2023新年在即新年的目的并非是拥有新的一年而是实现一个崭新的灵魂回顾2022这一年疫情常伴对我们的业务不是没有影响然而在这一年我们勇士球员强奸风波案!大学时期打球打的再好有什么用,那些并不是你可以胡作非为的理由。近日勇士队球星安东尼兰姆因大学时期的一宗强奸案被起诉,并且在女方再三劝阻下,一意孤行!如果事情被实锤,那这个不久前刚刚CBA赛季最大冷门!垫底队掀翻争冠劲旅队史首次连胜全队疯狂庆祝北京时间1月3日,CBA常规赛第22轮比赛打响,联赛副班长宁波和上海迎来了本赛季第三次交手。这场比赛无论过程和结果都令人意外,经过4节鏖战,宁波10697爆大冷击败上海,队史首次连