2020年面试整理,请指教,(2)关于jvm的整理

对于jvm这块纯属浅谈,平时研究少,有什么建议,或者有什么深入的理解欢迎大家指点,毕竟是来自一个小白的阐述,三克油爱V宝dei......阐述过程中有什么不妥,可以承受住帅哥美女前辈们的枪林弹雨,皮厚,哈哈哈

先盗个图先

2020年面试整理,请指教,(2)关于jvm的整理_第1张图片

jvm,Java虚拟机,这样说有点废话,经百度官方解释,这玩意是由软件技术模拟出来计算机运行的一个虚拟计算机,像我们编写Java的程序,是不能被操作系统直接识别的,这是jvm就是负责把我们的程序翻译给系统听,告诉系统我们的程序需要干什么...

编写的程序需要经过编译后产生class文件,jvm才能识别并运行他,这下就扯下jvm中的内存模式,寄存器啦,静态域啦,常量池啦等等,(1)寄存器,我们无法控制,人家自己的东西(2)静态域,我们自己的,像代码中static定义的静态成员变量(3)常量池,还是我们自己的,编译时被确定保存在class文件中的final常量值,这玩意大家编码过程中没少遇到吧,如,类、接口的全限定名,字段的名称,描述符,方法名称等(4)非RAM存储,硬盘永久存储空间(5)堆内存,他就是我们在代码中new的数组,对象,类等,这个得多说下,jvm中堆是运行时数据区,所有的类的实例和数组都是在堆上分配内存的,在jvm启动的时候被创建,由GC自动回收(6)栈内存,代码中基本类型的变量和对象的引用变量

个人理解内存模式就是这个...

所以说,类加载过程就是读取class文件到内存中,放入方法区,并在堆内存上创建一个Java.lang.class类型对象,这个对象封装了类在方法区的数据结构,一般类在使用时被加载,如使用new关键字创建类实例,访问静态变量,调用静态方法,反射,初始化子类等

类是如何实例化的?

(1)new语句创建,很常用

(2)使用class类的newInstance方法,调用无参构造函数创建,如Uaser u = User.class.newInstance()或者Uaser u = (User)class.forname(....).newInstance()

(3)使用constructor类创建newInstance方法,运用反射手段,如Object o = Class.forName(...).newInstance()

(4)调用clone()

无论何时调用,jvm会创建讴歌新的对象,将前边的对象全部拷贝进去

User u = (User)u1.clone()

(5)使用反序列化

调用Java.io.objectInputStream对象的readObject()

介绍到这,也就看出jvm的生命周期:创建势力,运行实例,实例消亡

jvm会在程序开始执行的时候他才运行,程序结束的时候它就停止,这里面包含守护线程和普通线程,守护线程也就是我们说的GC垃圾回收,是jvm自己使用的线程。

说了这些,再说说Java垃圾回收,在Java中,开发者不需要去释放一个内存,而是jvm自己执行,在jvm中有一个垃圾回收线程,他是低优先及的,在正常情况下不会执行,只有在jvm空闲或者当前堆内存不足的情况下才会触发执行,扫描那些没有被任何引用的对象,并将他们添加到要回收的集合中进行回收,那么如何判断一个对象是否存活,采用GC判定,如下

(1)引用计数器,对象引用+1,引用失效-1,当为0时就说明该对象没有被引用,也就是死对象,进行回收

(2)可达性算法,引用链法,从jvm栈中引用的基本类型变量和对象,方法区的静态引用变量,常量池中引用的对象等进行搜索,没有任何引用链相连时,则此对象不可用

那么这些过程中会有内存泄漏吗?

有,当然有,所谓的内存泄漏就是指不引用却一直占用内存的,如缓存时,我们定义一个全局的map,然户一直不用,但这个map一直被缓存引用,却不使用,就造成了内存泄漏,具体的规避方法如下:

(1)尽早释放无用的对象引用

(2)对字符串处理时,使用StringBuffer,因为string类是一个不可变的,独立占用着一块内存区域

(3)尽量少用全局的静态变量,因为GC不会回收

(4)避免集中创建对象

  (5)使用对象池

(6)不要再循环中创建对象

(7)优化配置

 

还有一个面试过程中会被问道,就是什么是双亲委派模型

这玩意就是当一个类收到类加载请求时,她不会自己先去加载,而是将请求委派给父类,这个父类不是我们说的集成关系,只是个调用逻辑,委派给父类后,由父类去加载,如果父类不能加载,则反馈给子类,由子类去完成加载

使用双亲委派的优点:

(1)使类具有优先级层次关系,可以避免类重复加载

(2)防止核心API被随意篡改,如通过不安全网络渠道获取一个名为Java.lang .Integer类,通过双亲委派传递到启动类加载器,而启动类中发现这个类已经被加载了,就不会重复去加载,而是直接返回已经加载了

 

你可能感兴趣的:(java)