JVM深入浅出(二)
Java代码的执行流程以及字节码 对于码农来说,写的都是一个一个的xxx.java文件,只有码农认识,机器是不认识这些文件的。这一堆的java文件必须要经过一个编译的过程,变成一堆的xxx.class文件,这个class文件是放在方法区里面(jdk1.8是MetaSpace)。
这一堆的xxx.class文件要通过ClassLoader加载到运行时数据区。
文章图片
代码举例说明:
编写一个java文件,
文章图片
编写之后编译一下,可以到相应的目录看到.class文件
文章图片
那么如何通过这个class文件拿到字节码呢?可以用javap这个命令(看帮助)
可以通过javap -c JVMDemo.class,显示的就是字节码
文章图片
从上面可以看出,public class JVM.JVMDemo这个类里面有两大部分组成,一个是构造器,一个是main方法。
看详细信息,可以这样执行:javap -verbose -c JVMDemo.class
可以看到很多很多字节码信息,从这些信息可以一步一步推断出java代码是怎样的,很多反编译工具就是这样做的。这个地方以后有时间慢慢学习,这里不讲了。
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3
JVM运行时数据区 JVM是支持多线程执行的。每个线程都会有一个它自己的计数器,也都会一个它自己的JVM虚拟机栈。程序计数器、虚拟机栈、本地方法栈都是线程私有的,不存在线程安全问题,而堆和方法区是线程公有的。
计数器:指向当前线程正在执行的字节码指令的地址(行号)。
虚拟机栈:存储当前线程运行方法时所需要的数据,指令和返回地址。
本地方法栈(native):本地方法运行时所需要的数据,指令和返回地址。
方法区:类信息、常量,如运行时常量池、字段和方法数据,以及方法和构造函数的代码。
堆(heap):对象、数组。
虚拟机栈:你写一个代码,里面会有很多方法,这个JVM虚拟机栈的作用就是调用执行任何方法的时候,都会给对应的方法创建栈帧,然后入栈,当某个方法被执行完了之后就会从虚拟机栈里面移走。个人理解就是:有一个栈,会把代码里的方法都做一个序号,放里面,哪个先执行哪个后执行,先执行的执行完之后被移走,然后执行下一个方法。
有个经典的异常:StackOverflowError
文章图片
文章图片
通过字节码深度分析使用加号进行字符串拼接的低性能 java中用于处理字符串常用的有三个类:
1、java.lang.String
2、java.lang.StringBuffer
3、java.lang.StrungBuilder
String、StringBuffer和StringBuilder的区别
- 对象的可变与不可变
String对象不可变,StringBuffer和StringBuilder对象可变。
- 线程是否安全
String中的对象是不可变的,也就可以理解为常量,所以线程安全。
StringBuffer中的方法大都采用了synchronized关键字修饰,所以是线程安全的。
StringBuilder没有对方法进行加同步锁,所以是非线程安全的。
- 字符串追加速度比较
StringBuilder > StringBuffer > String
- 【JVM深入浅出(二)】StringBuffer和StringBuilder的共同点
抽象类与一个接口的区别是:抽象类中可以定义一些子类的公共方法,子类只需要增加新的功能,不需要重复写已经存在的方法;而接口中只是对方法的申明和常量的定义。
StringBuilder和StringBuffer的方法都会调用AbstractStringBuilder中的公共方法,如super.append(…)。只是StringBuffer会在方法上加上synchronized关键字,进行同步。
如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer。
总结一下:
String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用于多线程下在字符缓冲区进行大量操作的情况
参考:
https://blog.csdn.net/bug_moving/article/details/80101136
https://www.cnblogs.com/haofuqi/p/4826262.html
https://www.cnblogs.com/weibanggang/p/9455926.html
推荐阅读
- EffectiveObjective-C2.0|EffectiveObjective-C2.0 笔记 - 第二部分
- 遇到一哭二闹三打滚的孩子,怎么办┃山伯教育
- 赢在人生六项精进二阶Day3复盘
- 2019年12月24日
- 陇上秋二|陇上秋二 罗敷媚
- 一百二十三夜,请嫁给我
- 迷失的世界(二十七)
- 我要我们在一起(二)
- 基于|基于 antd 风格的 element-table + pagination 的二次封装
- (二)ES6第一节变量(let|(二)ES6第一节变量(let,const)