扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
java虚拟机有自己完善的硬件架构。如处理器,堆,栈,寄存器,指令系统。JVM的主要工作是解释自己的指令集(即字节码文件)并映射到本地的CPU指令集或OS系统的调用。
创新互联建站2013年至今,先为江安等服务建站,江安等地企业,进行企业商务咨询服务。为江安企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。2.虚拟机整体结构3.JVM虚拟机各部分详解 3.1 --装载器子系统从入口处按需装载.class文件到运行时数据区域,执行数据的初始化工作,供执行引擎执行。
装载器一般分为两大类:启动类装载器,用户自定义装载器
启动类装载器又分为:引导类装载器,拓展类装载器,系统类装载器
注意: 将自定义的类放到lib文件夹下,该类的加载由扩展类加载器来加载。出于安全考虑,引导类加载器不会加载陌生的类。
3.2 --运行时数据区域装载器的装载流程可以分为大体上分为三个阶段。详细可分为五个阶段。
大体可分为:加载——链接——初始化
详细可分为:加载——检验——准备——解析——初始化
运行时数据区域可分为:方法区,堆区,java栈区,本地方法栈,程序计数器。
3.2.1 ——程序计数器(独立互不影响)1.每运行一个JVM实例,系统都会分配一块内存空间用来存储数据,由JVM自行管理。
2.在运行时数据区域中,方法区和堆区是JVM实例中所有线程共享的。java栈,本地方法栈,程序计数器都是线程私有的。随着线程的创建而创建,随着线程的结束而消亡。
3.在运行时数据区域中。程序计数器是唯一不会造成内存溢出的内存区域。
4.在运行时数据区域中,堆区是垃圾回收机制的主要活动区域。
程序计数器也可以叫做行号指示器,是线程私有的,线程创建时创建,线程结束时消亡。用来存储当前正在执行的字节码的指令地址或偏移量,可以持有下一行字节码指令的地址。当访问本地方法(native)时,程序计数器的值为undefined,不存储任何信息。
将程序计数器设置为线程私有的原因
程序计数器是一块内存区域,用来记录线程当前要执行的指令地址。线程是占用CPU执行的基本单位。而CPU一般是使用时间片轮询方式让线程轮询占用的,所有当前线程CPU时间片用完之后,就需要让出CPU,等下次轮到自己再执行。所以设置为线程私有,就是为了记录线程让出CPU时间时执行的指令地址。等到再次获得CPU时间片就能够按照记录的指令地址继续执行。
java栈也是线程私有的,在线程启动时创建,JVM只能进行压栈,弹栈操作。在访问方法时进行压栈操作,方法结束时进行弹栈操作。超出栈内存会抛出栈内存溢出错误。
java栈可细化为:本地变量数组,操作栈帧,方法所属类的常量池引用
java栈也可细化为:局部变量数组,操作栈帧,动态链接,方法出口。
两个划分本地操作相同,只是定义不同。
划分方式一:
划分方式二:
3.2.4 —— JAVA堆1.通过JavaNativeInterface(JNI)本地方法接口调用本地方法(其他编程语言编写的代码),根据每个方法语言类型会创建相应的栈,用于存储每个本地方法的调用状况。基本情况与JAVA栈类似。
2.本地方法栈是线程私有的。
1.在虚拟机启动时创建,内存占用大,是JVM实例中所有线程共享的内存区域,内存空间不连续,运行速度最慢,需要GC回收机制。
2.只要通过new创建的对象内存都在堆中分配。堆空间溢出会导致程序崩溃,所以当对象执行结束时,其占据的内存空间需要等待GC进行回收。
什么时候堆中的元素会被作为垃圾元素等待回收?
当堆中元素在栈中没有变量指向时,会被认为是垃圾等待GC回收。
如何判断是否回收(个人理解)
1.引用计数法(缺点:无法解决循环引用问题)
当堆中元素被使用时,计数器加1,结束使用,计数器减1。当计数器最后为0时,表示队中元素没有被使用,能被进行回收。
2.可达性分析法
当元素的使用通过节点形式进行连接。在判断节点是否被回收时,通过查找节点分支,当节点分支无任何链接,表示可以被回收
创建对象,首先会存入Eden区和s1区(From Survivor区域),当Eden满了,就会启动minor gc 回收不再使用的对象,将Eden和s1区中存活的对象放到s2区(To Survivor区域),剩下进行清除。s1和s2交换角色。如果经过多次清除还保留的元素会被放到老年代中。当Eden,s1,s2区都被占满后,就会将创建的对象放到老年代中。老年代占满之后就会触发FullGC回收堆,方法区对象。
1.复制算法(缺点:内存使用率降低)
复制算法:将内存空间分为两份,每次只占用其中一份,当空间被占满之后,就会将该空间所有存活的对象放到另一半的空间中,将原来那一半空间对象进行清除。
2.标记清除(缺点:会产生很多碎片空间)
标记清除:将需要回收的对象进行标记,当空间被占满后,清除标记的对象。
3.标记整理
标记整理:将需要回收的对象进行标记,并向一边移动,当空间占满后,清除标记的对象。
3.2.5 ——方法区内存泄漏:不断有新增对象长期不被回收,导致老年代挤压,全量线程阻塞。
场景:
1.类静态属性
2.未关闭资源。流,数据库连接
3.Threadlocal,每个线程中都会有Threadlocal变量副本,线程不结束,不清除。尤其是线程池
的情况。
1.和堆一样,是所有线程共享的,1.8之前称为永久代,1.8之后称为元空间,内部逻辑也发生改变。二者大的区别就是,永久代占用的是JVM的内存空间,而元空间占用的是本地内存空间。
2.主要用来存放已被虚拟机加载的类型信息(包括类,接口,枚举,域,方法等),常量,静态资源,即使编译器编译后的代码缓存等。
3.内存空间不连续,和堆一样,可选择固定大小或扩展。
4.方法区垃圾回收主要是两部分内容:【常量池中不使用的常量】【类的卸载】
执行引擎(将字节码文件转换成机器码文件)
第一代解释器
JVM一条一条读取,解释并执行字节码指令,解释执行,解释快,执行慢。
第二代解释器(即时编译器(JIT编译))
代码第一次执行被编译之后,存入缓存中。第二次使用,直接从缓存中拿。
第三代解释器(自适应编译器)
代码执行时机比JIT编译迟,先将程序以某种方式运行起来,收集信息进行动态编译,在代码执行过程中监控代码执行频率,缓存利用率高的代码。
HotSpot(混合模式的执行引擎)-【解释器,自适应编译器】
将需要编译的热点代码编译到本地代码,发现不频繁使用时,将本地代码从缓存中移除,重新进行解释执行。
1.-Xms:设置堆空间最小内存
2.-Xmx:设置堆空间大内存
3.-XX:NewSize,设置新生代最小大小
4.-XX:MaxNewSize,设置新生代大空间代销
5.-XX:PermSize,设置方法区最小空间
6.-XX:MaxPermSize,设置方法区大空间大小
7.-Xss:栈大小
8.Jps:查看进程相关信息
9.Jstat:JVM运行时状态信息,内存信息,垃圾状态
10.JInfo:JVM参数
11.JStack:线程快照,可定位死锁,死循环。
12.top:动态查看当前占用最多的CPU进程
13.top -Hp 进程ID :进程CPU使用率占用最高CPU进程ID。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流