jvm是什么
java的虚拟机。
-
JVM的位置
位置在操作系统之上,应用程序之下。 -
JVM的体系结构
- .java文件通过javac命令编译为.class文件,通过累加载器放入运行数据区。
-
堆
-
jvm只有一个堆,每个线程会有各自的一个栈
-
大部分调优都是在堆里面进行操作的
-
具体存储对象的实例,引用放在栈里。一对一的关系
-
垃圾回收主要是针对于堆,如果垃圾无法回收了,堆满了就会OOM
-
大致分位一下三个区域
-
新生代
-
eden区
-
对象一旦被new出来,实例就会放在eden区
-
-
幸存0区(s0)
-
第一次GC(垃圾回收)没有被收回的实例,会被放入到s0
-
-
幸存1区(s1)
-
GC收集的算法是复制算法,当再一次GC时,会把s0没有被收集的实例和从eden区来的实例,将都会放入s1区,然后s0区清空。s0和s1是一个切换的过程。
-
-
-
老年代
-
实例每经历一次GC都会有标记+1,如果打到一定的次数(默认15次,可以通过参数控制),会进入老年代。
-
当老年代满了的时候,会进行一次FULLGC(重GC),会扫描整个堆进行垃圾回收。
-
-
永久代
-
逻辑上存在,物理上不存在
-
jdk1.6叫永久代 常量池放在方法区
-
jdk1.7 慢慢去永久代,常量池放在了堆里
-
jdk1.8 无永久代,常量池放在了元空间(可以理解永久代改名了)
-
-
-
-
栈
-
一种先进后出(FIFO)的数据结构
-
StackOverFlow就是压如栈的栈针太对了,超出大小了
-
栈跟线程的生命周期相同
-
栈存储的主要是:八大基本类型、对象的引用、方法的实例
-
-
本地方法栈
-
保存native方法进入区域的地址。(可以理解为 保存的就是c语言的接口。调用的过程叫JNI(Java Native Interface))
-
-
程序计数器
- 每个线程都有一个程序计数器,是线程私有的,就是一个指针, 指向方法区中的方法字节码(用来存储指向像一条指令的地址, 也即将要执行的指令代码),在执行引擎读取下一条指令, 是一个非常小的内存空间,几乎可以忽略不计
-
方法区
-
被所有线程共享。主要存储的是:静态变量、类的源数据、常量池等。
-
- .java文件通过javac命令编译为.class文件,通过累加载器放入运行数据区。
-
-
就是.java文件通过javac命令编译成.class文件,通过类加载进入运行时数据区的。
-
通过关键字new进行实例化。对象.getClass()获取class,通过getClassLoader获取具体加载的加载器。
-
根加载器(BootStrapLoader)、扩展类加载器(ExtensionClassLoader,一般加载jdk类库当中的类)、应用程序加载器(一般是我们自己创建的类,就由他加载)、自定义加载器(继承ClassLoader实现)
-
-
-
用于加载类的时候使用的机制,为了安全,保证不会加载同一个类
-
类加载时会从下到上去找有没有类加载器加载过,会一直向上委托如果有就会加载。
-
-
沙箱安全机制
- Java安全模型的核心就是Java沙箱
-
将Java代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本地系统资源访问。
-
待完善
-
本地方法接口
-
就是凡是带了native关键字的就代表,java解决不来了,需要调用c语言。
-
-
PC寄存器
-
每个线程都有一个程序计数器,是线程私有的,就是一个指针, 指向方法区中的方法字节码(用来存储指向像一条指令的地址, 也即将要执行的指令代码),在执行引擎读取下一条指令, 是一个非常小的内存空间,几乎可以忽略不计
-
-
三种JVM
-
Sun公司的 HotSpot
-
BEA公司的 JRockit
-
IBM公司的 J9VM
-
-
堆内存调优的相关命令
-
-Xms1m 设置初始化内存分配大小
-
-Xmx8m 设置最大分配内存
-
-XX:+PrintGCDetails //打印GC垃圾回收信息
-
-XX:+HeapDumpOnOutOfMemoryError // oom异常dump下文件
-
如-Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError
-
-
GC垃圾回收器
-
复制算法
-
S0区和S1区来回移动,但是每次移动完S0区和S1区有一个为空。
-
优点:没有内存碎片
-
缺点:空出一半的内存空间,浪费内存空间
-
-
标记清除
-
先标记一次,然后再清除一次
-
优点:不需要额外的空间
-
缺点:两次扫描,浪费时间,会产生内存碎片
-
-
标记压缩
-
在标记清除的基础上,加了一步操作,再次扫描吧存活的对象移动一端
-
优点:防止内存碎片的产生
-
缺点:三次扫描
-
-
引用计数
-
对象使用一次就计数+1,使用最少的对象将会被回收
-
计数器本身也会有消耗,引用记数法现在基本不用
-
-
-
JMM
-
java内存模型(Java Memory Model)
-
JMM定义了线程工作内存和主内存之间的抽象关系;线程之间的共享变量存储在主内存中,每个线程都有一个私有的本地内存
-
volatile关键字
-
子线程修改带有volatile修饰的变量时,会及时同步到主内存
-
在只有读或者写的操作的情况下建议使用volatile关键字修饰,这样可以提高一些并发时候的效率问题。对于一些一已经被加锁的变量则不需要加volatile关键字,因为这样无法发挥出它的优势
-
-
-
总结
-
1、搞懂什么意思,他是做什么的,有什么作用。
-