欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

jvm-常见问题

时间:2023-07-08
谈一下对jvm的理解 jvm是存在于操作系统上(Linux,Windows,Mac)的java程序是跑在jvm上的jvm是用c语言实现的安装JRE即包含安装了jvm环境,如果只是跑程序不需要安装jdkjvm一共有三种: sun公司的Hotspot,可通过java -version查看当前jvm版本IBM的J9VM JIT编译器BEA的 JRockit jvm的体系结构
JVM模型
class loader:类加载器根据《Java 虚拟机规范》中的说法,Java 虚拟机的内存结构可以分为【公有】和【私有】两部分。

私有指的是每个线程的私有数据,包括:PC寄存器、Java 虚拟机栈、本地方法栈。

公有指的是所有线程都共享的部分,指的是 Java 堆、方法区、常量池

Class Loader类加载器【重要!】

类加载器工作流程 类加载器作用 加载编译后的class文件加载后生成【可实例化对象实例的class模版类对象】

// carClass即为类模版对象Class carClass = Car.class;Car car = carClass.newInstance();

根据类模板对象【实例化对象】(new  对象)class模版类对象 与 普通类对象区别: 一个class文件对应一个class模板类对象,即不管Car.class执行多少个carClass,这些carClass都是同一个class模板对象java类加载器的类型 Bootstrap Loader:启动类加载器,也叫根加载器,其可加载到的类对应jre环境中rt目录下的jar包ExtClassLoader:扩展类加载器,其可加载到的类对应jre环境中EXC目录下的jar包AppClassLoader:应用程序加载器,即开发人员自定义的类,这些类会生成对应的应用程序加载类,比如Student加载类类加载器的加载机制 双亲委派机制: jvm接收到加载class文件的请求先使用【启动类加载器】加载该class文件,如果需要加载的类的全包名在rt下存在,则使用启动类加载器加载rt下的类再使用【扩展类加载器加载】最后【使用应用程序加载器】比如:新建一个 java.lang.String类,但是该类与【启动类加载器】中的String类重包且重名,则此时使用String类时,就会使用rt下的String类沙箱安全机制 目的:防止恶意代码被执行native关键字 凡是带了native关键字的方法,说明这java的作用范围达不到了,会去调用底层C语言的库;凡是带了native关键字的,会进入native本地方法栈,然后调用本地方法接口【JNI-Java native interface】JNI作用:扩展Java的使用,融合不同的编程语言为Java所用,比如C、C++程序结束器【线程独有】 每个线程都有一个程序计数器,作用是记住当前线程执行的位置。方法区【全局共享】 方法区可以看成是一个接口,对于方法区的实现,不同虚拟机中策略也不同。以我们常用的HotSpot虚拟机为例,其设计团队使用永久带来实现方法区,并把GC的分代收集扩展至永久带方法区中保存:
JDK1.6
JDK1.7
JDK1.8
栈【线程独有】 栈:首先是一种数据结构。栈里的数据是先入后出,可以将栈看成一个桶,先进的被压在了下层,后进的在上层。为什么main方法先执行,但总是最后结束? 先将main方法放到栈中如果在main方法中调用A方法,于是将A方法也放入栈中,压在main方法上如果在A方法中也调用B方法,同理将B方法也放入栈中,压在A方法上当B方法执行完成后,将B方法弹出栈接着继续执行A方法,当A方法执行结束时,将A方法弹出栈接着继续执行main方法,当main方法执行结束时,将main方法也弹出栈,至此,main方法执行结束栈的生命周期和线程同步,线程结束,占内存也被释放了。固栈中不存在垃圾回收问题栈里面存储哪些东西 属于八大基本类型的局部变量的值(String、类等属于引用类型,固栈中不存放String)属于引用类型的局部变量的引用(该引用指向的对象分配在了堆中)实例的方法1和2的理解:因为声明方法时,相当于往栈中放了一个栈帧,固该方法中声明的局部变量被分配与栈中如果栈中线程的深度 > 栈允许的总深度:StackOverFlowError【属于错误,错误会使程序停掉】 堆(Heap) 堆:先进先出,FIFO~>first into first out一个jvm只有一个堆堆内存大小是可以调节的类加载器加载了class文件后,会向堆中存放哪些东西呢 几乎所有的对象实例对象和数组都在堆中分配属于八大基本类型的成员变量,其引用和值均存在堆中的类对象里面(String、类等属于引用类型,固栈中不存放String)属于引用类型的成员变量,其引用和对象 均存在堆中的类对象里面综合2和3来说,不管成员变量是基本类型还是引用类型,其引用、值或者是对象均存在与堆中jdk1.7以后,还保存了字符串常量池和静态变量垃圾回收主要就是作用于这里的堆中备份为三个区域 堆中垃圾回收机制:Minor GC和Major GC区别 Minor GC:简单理解就是发生在年轻代的GC。三步(复制--清空--互换)Major GC又称为Full GC。当年老代空间不够用的时候,虚拟机会使用“标记—清除”或者“标记—整理”算法清理出连续的内存空间,分配对象使用。新生代【Young】 新生区占对空间的1/3,包含:伊甸园区【Eden Space】、Survivor From区、Survivor To区,其比例为8:1:1伊甸园区:Java大部分新创建的对象都会被分配在伊甸园区,如果对象太大则会直接分配到老年区,当伊甸园区的内存不够时,会触发Minor GC复制算法的GC回收对象新生区的处理机制: 第一次Yong GC(Minor GC)后,Eden区还存活的对象复制到Surviver区的“To”区,“From”区还存活的对象也复制到“To”区,再清空Eden区和From区,这样就等于“From”区完全是空的了,而“To”区也不会有内存碎片产生,等到第二次Yong GC时,“From”区和“To”区角色互换,很好的解决了内存碎片的问题。对象在Survivor区中每“熬过”一次GC,年龄就会+1。待到年龄到达一定岁数(默认是15岁),虚拟机就会将对象移动到年老代老年代【Old】 主要存放应用程序中生命周期长的内存对象老年代的对象比较稳定,所以MajorGC不会频繁执行MajorGC采用标记清除算法:首先扫描一次所有老年代,标记出存活的对象,然后回收没有标记的对象。MajorGC的耗时比较长,因为要扫描再回收。MajorGC 会产生内存碎片,为了减少内存损耗,我们一般需要进行合并或者标记出来方便下次直接分配。当老年代也满了装不下的时候,就会抛出OOM (Out of Memory)异常永久区【Perm,JDK1.7以前】 内存的永久保存区域,主要存放Class 和meta (元数据)的信息GC不会在主程序运行期对永久区域进行清理。所以这也导致了永久代的区域会随着加载的Class 的增多而胀满,最终抛出OOM异常。元空间【jdk1.8及以后】 在jdk1.8以后,jvm使用元空间替代了永久区,固1.8的jvm模型如下:区别:元空间的内存使用的本地的物理内存,不再使用jvm的堆内存元空间保存:类信息、运行时常量池

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。