1.java能在跨平台使用

主要是因为我们将.java 源文件通过jvm编译为.class文件 在运行的时候java虚拟机会一行一行的执行字节码文件,操作系统是不认识java的  所以对于不同的平台有不同的java虚拟机 编译为不同操作系统的字节码文件

2.java 虚拟机的执行过程

先说几个概念

类装载器(ClassLoader):主要负责加载class文件

堆:它是Java虚拟机用来存储对象实例的,比我们在开发过程使用的new对象,只要通过new创建的对象的内存的对象都在堆分配,注意一点的是堆中的对象内存需要等待垃圾器(GC)进行回收,也是Java虚拟机共享区。

栈:栈内存,负责Java程序的运行,它是在线程创建时创建的,所以生命周期也是和线程生命周期一致,同时消亡,线程结束了栈也就释放,特别提醒的是栈不存在垃圾回收的问题,因为线程结束栈就是释放了。平时我们写的类变量、引用类型变量、实例方法等等都是在函数的栈内存分配好。(栈帧 包括 局部变量,操作数栈,动态链接(符号引用转为直接引用),方法出口)(一个方法是一个栈帧)

本地方法区:主要作用是登记native方法,然后在execution engine执行的时候加载本地方法库(例如new thread)

方法区(元空间):线程共享的,谁都可以共享使用,我们通常用来保存装载类的元结构信息。(就是加载的类放到方法区里,字节码相关信息)(常量,静态变量,类元信息(有什么方法,名称,修饰符))

 

程序计数器:是指方法区中的方法字节码由引擎读取下一条指令,它是一个非常小的内存空间。为什么有这种东西呢,大家都知道每个线程都是有一个程序计数器的,是线程私有的,相当一个指针。

堆和栈的关系  栈中new对象的引用指向堆

方法区与堆的关系(对象静态变量的)

jvm编译为.class字节码文件之后  通过类装载子系统 装载到运行时数据区中  然后通过字节码执行引擎执行

 

jvm 垃圾回收

jvm内存区域分为 新生代和老年代 新生代1/3 老年代2/3  新生代分为 eden区和 survivor区  eden8/10 survivor2/10

survivor 分为form to 各占1/2

gc分为 minor gc与full gc

minor gc 有引用的放到form区 无引用的回收掉(引用指的是gc root 根节点)

放到form区后 分带年龄加1   当在此minor gc 的时候同时会回收form区(并清空) 放入to区 分带年龄继续加一

在form区和to区轮询 在minor gc执行15次并没有回收  直接迁移到老年代(例如线程池,连接池,缓存数据,静态变量)

当老年代被放满的时候执行full 对整个对执行垃圾回收

当full gc 和minor gc 回收时会停止用户的应用线程 专心执行垃圾回收

调优

调优主要是 减少垃圾回收的次数 减少full gc的执行时间 大量的fullgc 就是元空间满了  把元空间的内容调大点

form 和to 区的

 

可以利用gc 日志执行调优,调整各区的内存分配

 

记录在JVM参数中一定要设置-XX:+HeapDumpAfterFullGC和-XX:+HeapDumpOnOutOfMemoryError两个参数,可以在发送FGC和OOM的时候将当时的Java堆情况

 

 

 

 

 

 

 

 

 

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐