无名商城论坛

搜索
查看: 1166|回复: 0

[TSD/原创] 【解忧】最全的JAVA知识汇总(附讲解和思维导图)

[复制链接]

1万

主题

1万

帖子

3万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
32464
发表于 2022-5-8 20:37:40 | 显示全部楼层 |阅读模式

jvm 一行代码是怎么运行的

首先,java代码会被编译成字节码,字节码就是java虚拟机定义的一种编码格式,需要java虚拟机才能够解析,java虚拟机需要将字节码转换成机器码才能在cpu上执行。 我们可以用硬件实现虚拟机,这样虽然可以提高效率但是就没有了一次编译到处运行的特性了,所以一般在各个平台上用软件来实现,目前的虚拟机还提供了一套运行环境来进行垃圾回收,数组越界检查,权限校验等。虚拟机一般将一行字节码解释成机器码然后执行,称为解释执行,也可以将一个方法内的所有字节码解释成机器码之后在执行,前者执行效率低,后者会导致启动时间慢,一般根据二八法则,将百分之20的热点代码进行即时编译。JIT编译的机器码存放在一个叫codecache的地方,这块内存属于堆外内存,如果这块内存不够了,那么JIT编译器将不再进行即时编译,可能导致程序运行变慢。

jvm如何加载一个类

第一步:加载,双亲委派:启动类加载器(jre/lib),系统扩展类加载器(ext/lib),应用类加载器(classpath),前者为c++编写,所以系统加载器的parent为空,后面两个类加载器都是通过启动类加载器加载完成后才能使用。加载的过程就是查找字节流,可以通过网络,也可以自己在代码生成,也可以来源一个jar包。另外,同一个类,被不同的类加载器加载,那么他们将不是同一个类,java中通过类加载器和类的名称来界定唯一,所以我们可以在一个应用成存在多个同名的类的不同实现。

第二步:链接:(验证,准备,解析) 验证主要是校验字节码是否符合约束条件,一般在字节码注入的时候关注的比较多。准备:给静态字段分配内存,但是不会初始化,解析主要是为了将符号引用转换为实际引用,可能会触发方法中引用的类的加载。

第三步:初始化,如果赋值的静态变量是基础类型或者字符串并且是final的话,该字段将被标记为常量池字段,另外静态变量的赋值和静态代码块,将被放在一个叫cinit的方法内被执行,为了保证cinit方法只会被执行一次,这个方法会加锁,我们一般实现单例模式的时候为保证线程安全,会利用类的初始化上的锁。 初始化只有在特定条件下才会被触发,例如new 一个对象,反射被调用,静态方法被调用等。

java对象的内存布局

java中每一个非基本类型的对象,都会有一个对象头,对象头中有64位作为标记字段,存储对象的哈希码,gc信息,锁信息,另外64位存储class对象的引用指针,如果开启指针压缩的话,该指针只需要占用32位字节。

Java对象中的字段,会进行重排序,主要为了保证内存对齐,使其占用的空间正好是8的倍数,不足8的倍数会进行填充,所以想知道一个属性相对对象其始地址的偏移量需要通过unsafe里的fieldOffset方法,内存对齐也为了避免让一个属性存放在两个缓存行中,disruptor中为了保证一个缓存行只能被一个属性占用,也会用空对象进行填充,因为如果和其他对象公用一个缓存行,其他对象的失效会将整个缓存行失效,影响性能开销,jdk8中引入了contended注解来让一个属性独占一个缓存行,内部也是进行填充,用空间换取时间,如何计算一个对象占用多少内存,如果不精确的话就进行遍历然后加上对象头,这种情况没办法考虑重排序和填充,如果精确的话只能通过javaagent的instrument工具。

反射的原理

反射真的慢么?

首先class.forname和class.getmethod 第一个是一个native方法,第二个会遍历自己和父类中的方法,并返回方法的一个拷贝,所以这两个方法性能都不好,建议在应用层进行缓存。 而反射的具体调用有两种方式,一种是调用本地native方法,一种是通过动态字节码生成一个类来调用,默认采用第一种,当被调用15次之后,采用第二种动态字节码方式,因为生成字节码也耗时,如果只调用几次没必要,而第一种方式由于需要在java和c++之间切换,native 方法本身性能消耗严重,所以对于热点代码频繁调用反射的话,性能并不会很差。

属性的反射,采用unsafe类中setvalue来实现,需要传入该属性相对于对象其始地址的偏移量,也就是直接操作内存。其实就是根据这个属性在内存中的起始地址和类型来读取一个字段的值,在LockSupport类中,park和unpark方法,设置谁将线程挂起的时候也有用到这种方式。

动态代理

java本身的动态代理也是通过字节码实现的

Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)




回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表