java虚拟机jvm学习笔记
java虚拟机:java是跨平台的语言,一处编译,处处运行。原因是因为有java虚拟机,不同的操作系统底层的机器码是不同,虚拟机的作用就是对应操作系统,输出对应的机器码。
备注:java:java.java经过编译变成java.class 字节码文件,再通过java虚拟机运行。
java虚拟机分为:类加载子系统;jvm运行时数据区:堆、方法区、栈、本地方法栈、程序计数器;执行引擎。
执行引擎:硬件层面:cpu;软件层面:主线程。
线程共享数据:堆、方法区(元空间)。
线程私有数据:栈、本地方法栈、程序计数器。
并发问题是因为:线程共享数据,导致输出结果不一致。
栈:数据结构,存储, 先进后出(压栈、弹栈,栈里每个方法叫栈帧)。
栈帧:局部变量表;操作数栈;方法出口。
反编译:cmd javap;javap -c java.class;java.text。(根据jvm指令手册即可看懂反编译后文件)
程序计数器:指向当前线程所执行的字节码指令的(地址)行号。
堆:存放对象(栈指向堆)。
本地方法栈:用native修饰的方法,底层由c或者c++实现。
对象与类的关系:对象存在堆,类存放在元空间,对象指向类,即堆指向元空间(方法区)。
堆:新生代(1/3):Eden(8/10)、s0(1/10)、s1(1/10);老年代(2/3)。
堆的存放:对象一开始存在在堆的Eden区里,当Eden的内存占满了,会调用minor gc 进行垃圾回收,若对象无引用了则回收,有引用则进入s0(对象加1岁)。当第二次调用minor gc时,s0的依然未被回收时,将s0的对象转移到s1,对象继续加1岁,当对象年龄打到阈值或者内存占用达到50%依然未被回收的时候,对象会转移到老年代,当老年代内存不足时(内存溢出),会调用full gc ,回收整个堆,造成线程全部挂起。(s0与s1互相复制拷贝交换)
为什么java需要内存调优?(新生代垃圾回收:minor gc)
因为软件是运行在硬件之上的,硬件内存是有限的,当软件运行越久,内存占用就越大,当内存占用过大时,会与其他软件抢占内存,造成性能问题,超过硬件内存时,电脑会卡死,所以需要对软件进行内存调优,即对软件运行占用的内存设置临界点,当超过或打到临界点时,java运行垃圾回收机制,回收内存。这样做可以提升性能,也可以延长硬件寿命,并且还能降低硬件成本。(java是自己进行内存管理的:在有限的事情里,做无限的事)
如何调优?(javaVsiualVM,可查看内存占用)
对堆内存进行调优,避免full gc的调用
ps:这只是jvm的一部分,想要了解更多,需要深入学习jvm
ps:c c++ 也是跨平台 因为java底层就是c和c++
ps:笔记不一定写的够精准,后续持续改进。