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

JVM经典面试问题(内存溢出和内存泄露)解答及调优实战分析

  常见问题及调优实战1、内存泄漏与内存溢出的区别
  内存泄漏(Memory Leak):指的是对象无法得到及时的回收,导致其持续占用内存空间,造成了内存空间的浪费。 内存泄露一般是强引用才会出现问题,其他像软引用,弱引用和虚引用影响不大。
  内存溢出(Out Of Memory):内存泄漏到一定的程度就会导致内存溢出,但是内存溢出也有可能是大对象导致的。
  这两个区别结合下面的问题2可以更好的理解。2、如何防止内存泄露
  我们先来看下面一个简单的例子:package com.zwx.jvm;  public class JVMTuningDemo {     public static void main(String[] args) {         {             byte[] bytes = new byte[1024 * 1024 * 64];         }         System.gc();     } }
  调用之后打开gc日志,如果不知道怎么获取gc日志的,可以点击这里。
  可以看到GC之后,对象并没有回收掉,从代码上来说,因为有{},所以理论上已经离开作用域了,bytes会被回收(如果不加{}是肯定不会被回收的,因为没有离开作用域),但是这里为什么还是没有被回收?
  回答这个问题之前我们先对上面的代码改进一下package com.zwx.jvm;  public class JVMTuningDemo {     public static void main(String[] args) {         {             byte[] bytes = new byte[1024 * 1024 * 64];             bytes = null;         }         System.gc();     } }
  这时候再来看,会发现已经被回收了
  这是因为之前虽然已经离开作用域了,但是却并没有收回引用,也就是说栈帧中的局部变量表数组中所对应的slot(局部变量表中数组的每一个位置都被称之为slot)还是有值的,并没有被切断引用,而将其置为Null就等于切断了引用,所以可以被回收。
  如果看过我的并发编程系列文章中对AQS同步队列以及阻塞队列的源码分析,那么也应该可以看到,这些源码中也是大量使用了这种方式来帮助虚拟机进行gc:
  在有些场景这种设置为null的方式确实是一种解决方式,但是其实最优雅的方式还是以恰当的变量作用域来控制回收变量。
  我们再对上面的例子进行改写:package com.zwx.jvm;  public class JVMTuningDemo {     public static void main(String[] args) {         {             byte[] bytes = new byte[1024 * 1024 * 64];         }         int i = 0;         System.gc();     } }
  运行之后打开gc日志:
  我们会发现,bytes对象确实也被回收了,这又是为什么呢?
  这是因为栈帧中的局部变量表内的每一个slot都是可以复用的,当bytes变量离开了其作用域之后,Java虚拟机知道这个slot已经无效了,但是虽然无效,引用却还在,所以如果没有新的变量过来占用bytes变量所在的slot,是无法将bytes回收的,而一旦有新的变量过来占用slot,自然而然bytes对象的引用就被切断了,从而被gc掉。3、GCRoot不可达的对象一定会被回收吗
  答案是不一定的。
  即使在可达性分析法中被判定不可达的对象,也并非是"非死不可"的,这时候它们暂时处于"缓刑阶段",对象依然有"逃生"的机会。
  一个对象在第一次被标记为不可达对象时,并不会立刻被回收,而是会进行判断是否有必要执行finalize()方法,那么什么时候会执行finalize()方法呢?有两种情况:1、Java虚拟机已经调用过当前对象的finalize()方法2、finalize()方法被我们重写了
  如果不满足这两种情况,那么对象就相当于是"死刑立即执行",没有机会逃生,但是一旦满足执行finalize()方法的条件,而我们又在finalize()方法中将对象重新和引用链中的对象进行了关联,这时候对象就可以顺利"逃生"。
  我们来看下面一个例子:package com.zwx.jvm;  import java.util.ArrayList; import java.util.List;  public class ObjEscapeByFinalize {     public static ObjEscapeByFinalize objEscapeByFinalize = null;      public static void main(String[] args) throws InterruptedException {         objEscapeByFinalize = new ObjEscapeByFinalize();         //首次自救         objEscapeByFinalize = null;         System.gc();         Thread.sleep(1000);//finalize()方法优先级比较低,稍微停顿一会等一等         print();          //再次自救         objEscapeByFinalize = null;         System.gc();         Thread.sleep(1000);         print();     }      static void print(){         if (null == objEscapeByFinalize){             System.out.println("obj has been gc");         }else{             System.out.println("obj escape success");         }     }      @Override     protected void finalize() throws Throwable {         System.out.println("come in method:finalize");         super.finalize();         objEscapeByFinalize = this;     } }
  运行结果为:come in method:finalize obj escape success obj has been gc
  从结果可以看到,第一次自救成功,而第二次已经没有了自救机会,因为当前对象已经执行过一次finalize()方法了,而如果我们把finalize()方法中的:objEscapeByFinalize = this;
  替换为:objEscapeByFinalize = new ObjEscapeByFinalize();
  这时候就可以一直自救成功,因为每次自救之后就产生了一个新的对象,新的对象并没有执行过finalize()方法。
  上面的demo还有一点需要注意的是,finalize()方法针对的是对象,假如上面的静态对象换成一个其他对象,而finalize()方法又写在当前对象,那么是无效的,例如如下例子:package com.zwx.jvm;  import java.util.ArrayList; import java.util.List;  public class ObjEscapeByFinalize1 {     public static List list = null;      public static void main(String[] args) throws InterruptedException {         list = new ArrayList<>();         //首次自救         list = null;         System.gc();         Thread.sleep(1000);         print();              }      static void print(){         if (null == list){             System.out.println("obj has been gc");         }else{             System.out.println("obj escape success");         }     }      @Override     protected void finalize() throws Throwable {         System.out.println("come in method:finalize");         super.finalize();         list = new ArrayList<>();     } }
  这里是无法实现自救的,因为这里要救的对象是List,而finalize()并不属于List,是属于ObjEscapeByFinalize1对象,所以这一点也是需要明确地。
  不过虽然finalize()可以完成对象自救,但是由于这个方法的代价比较大而且运行时有不确定性,一般情况下还是不建议使用4、Young GC会有STW吗
  不管是什么类型的GC,都会有 stop-the-world,只是发生时间的长短,目前Java中所有的垃圾回收器均需要STW,唯一的区别只是时间的长短问题。5、Major GC和Full GC的区别
  之前我们提到了,Major GC通常会伴随着Minor GC,也就等于触发了Full GC,但是虽然如此,Major GC和Full GC并不是完全等价的,因为Full GC 的同时会对方法区(jdk1.8的metaspace,jdk1.7的永久代)进行GC,所以严格来说:Full GC=Major GC+Minor GC+方法区GC6、方法区会发生GC吗
  答案是肯定的。虽然方法区中的回收收益一般都不高,但是也是会被GC的,而方法区中被回收的最主要的就是对废弃常量和无用类的回收,判定一个废弃常量比较简单,但是判定一个类是无用类是比较困难的,那么方法区中的怎么判断一个类是无用类呢?
  判断一个类是否无用,需要达到以下三个条件:1、该类所有的实例都已经被回收,也就是 Java 堆中不存在该类的任何实例。2、加载该类的类加载器ClassLoader已经被回收(从这个条件可以看出,一般只有大量使用了反射,动态代理或者字节码框架等场景条件下才会满足这个条件)。3、该类对应的 java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。
  这三个条件实际上是非常苛刻的,而即使达到以上三个条件,无用类也仅仅是可以被回收,但是是不是一定会被回收,还是取决于Java虚拟机。HotSpot虚拟机中提供了参数-Xnoclassgc来控制。7、什么是直接内存
  直接内存(Direct Memory)不属于运行时数据区,也被称之为堆外内存,通常访问直接内存的速度会优于Java堆。直接没存也有可能会发生OutOfMemoryError异常,Java 1.4中新加入的nio包下的ByteBuffer就操作了直接内存,直接内存可以通过参数-XX:MaxDirectMemorySize控制大小。8、CMS收集器和G1收集器的区别
  作为同样是并行的2款垃圾收集器,G1的目前是用来取代CMS收集器的,其主要有如下区别:1、CMS收集器是老年代的收集器,需要和其他新生代收集器配合使用,而G1同时适用于新生代和老年代,不需要和其他收集器配合使用2、CMS收集器以最小的停顿时间为目标的并发收集器,G1收集器是一种可预测垃圾回收的停顿时间3、CMS收集器是使用"标记-清除"算法进行的垃圾回收,容易产生内存碎片,G1使用了 Region方式对堆内存进行了划分,且基于标记整理算法实现,整体减少了垃圾碎片的产生9、类加载机制经过哪些步骤
  类加载机制主要经过了:加载(Loading),连接(Linking),初始化(Initialization),使用(Using),卸载(Unloading) 五个大阶段,而其中连接(Linking)又分为:验证(Verification),准备(Preparation),**解析(Resolution)**三个阶段。想要详细了解每个阶段做了什么事情,可以点击这里。10、系统CPU经常100%,如何定位1、首先要确认哪个进程占用CPU高,可以使用top命令
  2、找到之后可以继续执行top -Hp PID命令查询出占用最大的线程
  3、执行jstack命令生成线程快照信息:jstack -l 进程PID >jstack.log
  输出之后,我们找到上面占用CPU最高的一个线程pid=11566,将其转换为16进制,得到的结果是2d2e,然后进入生成的jstack.log文件找到这个线程可以查看线程信息。
  4、上面就可以定位到了线程调用的方法了,接下来就可以去分析对应的代码寻找问题了总结
  本文主要列举了一些其他比较经典的,而前面在JVM系列其他文章中又没有过多进行说明的问题,JVM学习之后需要不断实战积累调优经验,虽然还有一些理论在JVM系列中没有提及,但是我想如果可以认真把我 JVM系列至本篇为止的8篇文章相关知识和理论都掌握的话,那至少可以说已经具备了调优的理论基础了,剩下的就是不断积累经验,当然,推荐大家可以去通读一下JVM规范,毕竟所有的Java虚拟机都是按照JVM规范来实现的,或者有必要的可以自己去编译JDK来进行更深一步的研究。
汽车空调是如何制冷的?我们开车常用的汽车空调是如何进行制冷的?制冷都是由那些零件组成,每个零件的作用是什么?汽车空调系统制冷一般由压缩机总成冷凝器及储液罐总成HVAC总成(里面含有蒸发器和膨胀阀)和空调无线扫地机TELEC认证如何办理?无线扫地机TELEC认证流程有哪些?无线扫地机是智能家用电器的一种,能凭借一定的人工智能,自动在房间内完成地板清理工作。一般采用刷扫和真空方式,将地面杂物先吸纳进入自身的垃圾收纳盒蓝牙耳机CE认证怎么办理?CE认证的类型有很多种,很多人做CE认证时都不清楚自己的产品符合哪一种CE认证类型,任何进入欧洲市场的产品都需要做CE认证,而CE认证根据电子产品的不同而分不同的形式。出口欧盟的无搭载iMMD混动系统全新思域HATCHBACK混动版曝光,外观有变化日前,外媒曝光了一组全新思域HATCHBACK混动版路试谍照。据悉,新车将针对外观有所调涨,并搭载iMMD混动系统。相比思域三厢版车型,全新思域HATCHBACK混动版车身更为紧凑豪华智能旗舰领克09正式上市哪一款最具性价比?日前,领克品牌五周年庆典暨豪华智能旗舰SUV领克09上市发布会在上海盛大举办。此次,领克09共推出MHEV和PHEV两种动力版本,UltraHaloPro三款车型,其中,MHEV版2022款大众途观L到店搭载2。0T动力,配置更为丰富,你不心动吗作为上汽大众的当家花旦,途观系列创造了国内SUV销量的多项纪录。途观L车型的上市,不但配置更为丰富,而且进一步满足了当下消费者对于车内大空间的需求。目前,据编者了解到,北京地区20红旗LS7外观实拍车长或超过5。5米,定位旗舰SUV日前,网络上曝光了一组红旗LS7的实车外观实拍图。据悉,新车外观设计方正扎实,车窗配有深色车膜。从悬挂的试字号牌来看,该车仍处在测试环节中。新车前脸采用了面积硕大的进气格栅设计,车只需要一招就能让win10字体变得更好看我们都知道,Windows系统的字体不如Mac系统的字体好看,没有那么精致。Windows系统只有在高分屏下,4K分辨率下,字体才会好看,圆润。但是没有4K显示器的伙伴们,其实也可既能充电又能听歌的真无线耳机南卡N2S前言南卡可以说是国内比较知名的数码外设厂商,尤其是旗下的蓝牙耳机系列更是佼佼者。之前也用过其耳机产品还是挺不错的,而这次体验的新产品南卡N2S,是N2的升级产品,相对于一代产品,本燕飞利仕I600TWS真无线蓝牙耳机重量小长续航佩戴爽音质强前言对音响品牌不是特别有研究的消费者对燕飞利仕这个品牌可能比较陌生,但是如果你关注汽车音响方面的话,相信对这个品牌就不会再陌生了,因为很多汽车上配置的音响都是燕飞利仕。燕飞利仕是美看电影有感五一期间,看电影你的婚礼和扫黑。你的婚礼开始时觉得一般,后来到男主人公在事业受挫埋怨时,觉得挺实在。年轻人初入社会,遇到挫折是正常,其实再咬咬牙,也就过去了,只是当事人的苦只有自己
2021电视市场销量出炉,3835万台,销量下滑2021电视销量出炉,3835万台,下降百分之十三点八,有点无奈,当然这个正常,毕竟电视去年还是价格高,而且创新不够。电视现在看起来价格是降低了,面板价格看起来是有下滑的,但一个问我们为什么要控制碳排放?所谓碳排放,就是指以二氧化碳为主的温室气体排放,我们为什么要控制呢?我们生活的地球,可以吸收太阳光传来的热量,也可以把这种热量反射到外层空间去。可是地球上空有二氧化碳为主的几种气体BTC以太坊投资者正趋向长期投资前美联储审计经理比特币绝对是社会正义的工具1月17日消息,前美联储审计经理比特币顾问夏琳法迪雷波(Fadirepo)接受采访时表示,比特币绝对是社会正义的工具。Fadirepo称,华为反击,首选加拿大开刀,5G专利中断授权帮凶们要注意了,华为开始反击了。就在刚刚,华为开始反击,而且先拿加拿大开刀,到底怎么回事儿呢?最近华为呢连续开展了三项反击行动,让那些拆除华为5G设备拒绝华为的公司彻底慌了。尤其是实现从0到1突破!国产企业发布关键芯片,华为等到了?本文原创,禁止搬运和抄袭,违者必究!广大花粉都在等待华为能尽快回归5G,为用户带来先进的5G性能手机。但具体情况大家也都知道,手机能否用上5G涉及到的关键技术有很多,其中就包括了5小米首款屏下摄像头旗舰年货好价,加送100瓦无线充套装,买么?小米Mix4是小米的首款屏下相机手机,承载了mix系列探索未知的重任。现在,小米Mix4这款屏下摄像头旗舰12GB256GB版在都多多平台只要3819元,要知道该版本的发售价为62惨剧!2人当场死亡,自动驾驶又酿大祸?被控过失杀人罪!马斯克也摊上事了,被要求偿还830亿,啥情况?特斯拉的自动驾驶系统,再度被推上风口浪尖。近日,美国法院公布一则案件,引发了市场关注。一位特斯拉ModelS驾驶员被指控过失杀人罪,原因是开启L2自动驾驶系统后,造成交通事故致2人新网银行5周年数字技术助小微金融服务破题来源原创稿为了提高金融服务的深度与广度,2015年国家开启了民营银行的试点,先后有19家民营银行开业。其中,位于成都的新网银行于2016年12月28日开业,成为西部第一家民营银行,拍摄梅花折返镜头和微单搭配要注意的技术问题我们都知道,折返镜头摄影会出现迷人的圈圈。这是由折返镜头的镜头特性所决定的。由于这样的文章网络很多,内容也太专业,今天我们就不聊这个问题了我们聊一聊,折返镜头和微单怎么搭配。或者微纳米线技术可将太阳能电池效率翻倍挪威科技大学(NTNU)研究小组开发了一种使用半导体纳米线材料制造超高效率太阳能电池的方法。如将其用于传统的硅基太阳能电池,这一方法有望以低成本将当今硅太阳能电池的效率提高一倍。该Python其实很简单第十章字典与集合前面介绍的列表和元组都是有序序列,而字典与集合属于无序序列,也就是说,不能通过索引来操作元素。10。1字典语法格式dictionarykey1value1,key2value2,k