jvm


前言

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。


JVM体系结构

jvm位置:操作系统上一层。

java->.class->类加载器->jvm。

jvm简图

类加载器

加载Class文件。

虚拟机自带类加载器、启动类(根)加载器、扩展类加载器、应用程序加载器。

AppClassLoader、ExtClassLoader、

双亲委派机制

为了保证安全,Root->Exc->App,一直往上找,先执行根及父类,找不到再执行子类。

  1. 类加载器收到类加载请求。
  2. 将这个请求向上委托给父类加载器去完成,一直向上委托到根加载器。
  3. 根加载器加载不了则再层层往下委派。

沙箱安全机制

组成:

  • 字节码校验器:确保java文件遵循java规范。
  • 类加载器:
    • 防止恶意代码。(双亲委派)
    • 守护了被信任的类库边界。
    • 将代码归入保护域。

Native

Thread的start方法会去调用native的start0方法,因为jvm处理不了线程,需要跟操作系统调用,所以调用本地的start0方法。

//正常java类中不应该存在一个类似于接口的东西
//但是因为native所以导致它不不会报错
private native void start0();

带了native,jvm就管不到了,就会放入本地方法栈,再调用本地方法方法接口,从而调用本地方法库。这样就达到了扩展java的使用,达到了调用c语言的目的,也是当初为了兼容c而来。

PC寄存器

程序计数器:Program Counter Register

每个线程都有一个程序计数器,是线程私有的,是一个指针,用来存储指向一条指令的地址,在执行引擎读取下一条指令,是一个非常小的内存空间。

方法区

Method Area 方法区

方法区是被所有线程共享的,所有的字段和方法字节码,以及一些特殊方法,如构造函数、接口代码也在此定义。
静态变量、常量、类信息(构造方法、接口定义)、运行时的常量池存在方法区,但实例变量存在堆内存中

先进后出。main方法先执行后结束就是因为栈。

管理程序的运行,生命周期和线程同步,线程结束,栈内存就释放完了,所以不存在垃圾回收。

栈运行原理:栈帧。

Heap,一个jvm只有一个堆内存,堆内存大小是可以调节的。

类加载器读取了类文件后,会把实例对象的方法,常量,变量放在堆中。

堆内存还要细分三个区域:

  • (伊甸园)Eden Space。
  • 幸存0区。
  • 幸存1区。
  • 养老区。
  • 永久存储区。

堆内存
堆内存满了就会报OOM错误。
java.lang.OutOfMemoryError: Java heap space。

在jdk8以后,永久存储区改了个名字(元空间)。

新生区:类诞生、成长、死亡的地方。
伊甸园:所有对象都是在伊甸园new出来的。
养老区:99%的对象都是临时对象,经过不了幸存区的筛选。
永久区:这个区常驻内存,用来存放JDK携带的Class对象。Interface元数据,存储的是java运行时的环境或者类信息,不存在垃圾回收。关闭虚拟机会释放。一个启动类加载大量jar包,tomcat部署太多应用,大量动态生成反射类,就会出现oom。

  • jdk1.7:提出去永久堆,常量池在堆中。
  • jdk1.8:无永久代,改成元空间,方法区也放在元空间。

调节堆内存:-Xms1024m -Xmx1024m -XX:+PrintGCDetails。

打印出PSYoungGen total 305664K || ParOldGen total 699392K,新生区和养老区已经占用1024m,那么元空间则存在本地内存中。

出现oom,如何快速排查

内存快照分析工具,MAT,Jprofiler。

  • 分析Dump内存文件,快速定位内存泄露。
  • 获得堆中的数据。
  • 获得大的对象。

GC

垃圾回收,GC作用区域:堆(新生代,幸存区,老年区)。

轻GC(主要针对新生代)、重GC(全局GC)。

引用计数法(不常用)

计算对象被用了几次,清理最少的。

复制算法(新生区)

  • 每次GC都会将Eden伊甸园活的对象移到幸存区(to,from)中。
  • 幸存区谁空谁就是to,要保证有一个to,就需要复制幸存区一边数据到另一个幸存区。
  • 当一个对象经历了15次GC(默认)后还活着,就会进入养老区。
  • 好处:没有内存碎片。坏处:浪费内存空间。适合新生区。

标记压缩清除算法(老年代)

标记清除

标记存活对象
清除没有标记的对象。

缺点:两次扫描,浪费时间,会产生内存碎片。
优点:不需要额外空间。

标记压缩

再次扫描,防止内存碎片产生。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值