1、JVM概述
1.1 程序计数器
占用内存较小,是当前线程锁执行的字节码(JVM指令)行号指示器,JVM通过改变计数器的值来选取下一条要执行的指令。
多线程之间的程序计数器相互独立,互不影响,为了保证每个线程恢复之后,都能回到之前中断的位置,进而继续执行。
1.2java堆
一般所说的“堆”指的就是java堆,是用来存放java对象的,每一个java对象都是存放在堆中的。
Java是面向对象的编程语言,C++、Python也是面向对象的编程语言
问题:
面向对象编程语言和面向过程编程语言的区别?
面向过程关注每一步的具体细节,将程序细化到具体步骤。
面向对象是关注程序能够抽象出多少个数据模型,不需要关注具体的步骤。
比如:你开车去北京
面向过程:
1、打开车门 2、发动汽车 3、踩油门 … … 100、到北京
面向对象:
你、汽车、北京
你操作汽车到北京
Java堆是被所有线程共享的,Java内存结构中的大头,占用了大部分空间的是GC(垃圾收集器)的主要管理区域。
Java堆又分为年轻代、老年代、永久代
年轻代
又分为Eden区和Survivor区
Eden:伊甸园
Survivor:幸存者(Survivor From、Survivor To)
Eden:对象刚创建的时候,存放在Eden区
Survivor:GC回收的时候,将Eden存活(不需要回收)的对象存入Survivor From区,在下一次回收的时候,将From区不需要回收的对象存到To区,然后清理From区,在下下次回收的时候,将To区不需要回收的对象存入From区,再清理To区,依次循环… …
每次回收之后,存活下来的对象年龄都会+1,年龄增加到一定程度,移动到老年代中。
老年代
存放生命周期较长的对象
永久代
JDK1.7之前将类的信息存放在永久代中,JDK1.8之后去掉了永久代,改为元空间。
元空间和永久代是方法区的具体实现,方法区只是一种规范。
面试题:
1.7之前字符串常量池存放于永久代中,1.8之后去掉了永久代,1.8之后的字符串常量池放在堆中,为什么要这样处理?
因为永久代空间有限,创建字符串对象,需要调用inter方法
元空间使用的是本地内存,永久代使用的是JVM内存
本地内存有多大,元空间就有多大,不再受限于JVM内存大小,相当于开辟出更多的区域可以使用,效率更高。
1.3虚拟机栈
通常所说的栈就是虚拟机栈,Java方法的执行是在虚拟机栈中执行的,栈中存放的是栈帧,每个栈针对应一个被调用的方法,方法的执行其实就是入栈和出栈的过程。
栈帧包括:
1、局部变量表(Java方法中用到的变量)
2、操作数栈(数据入栈出栈)
3、动态链接(方法的返回地址,方法的出口)
每一个方法的执行,JVM都会创建一个栈帧,并且将栈帧压入栈中,方法执行完毕,该栈帧出栈。
2、编码规范
2.1强制编码规范
1、Java程序的文件名必须和类名一致
2、main方法是程序的入口,不能做修改,必须按照规范来写,除了参数的名称可以改。
2.2建议编码规范
1、代码要分行去写,不能写到一行
2、要注意代码的缩进,提高可读性