JVM相关概念入门

一、JVM位置:在这里插入图片描述
二、JVM体系结构:
在这里插入图片描述
垃圾回收器在执行引擎中,JVM调优一般都是在方法区和堆中;

三、类加载器:
作用:加载class文件;
在这里插入图片描述
1、虚拟机自带的加载器;
2、启动类(根)加载器;
3、扩展类加载器;
4、应用程序加载器;

当我们要使用某个类的时候,顺序是这样的,首先先去启动类加载器bootstrap找,如果有就直接用,如果没有就去扩展类加载器找,如果扩展类加载器没有,就去应用程序加载器找,如果还是没有,就报ClassNotFoundException异常。
在这里插入图片描述

双亲委派机制:
1、如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类加载器去执行;
2、如果父类加载器还存在其父类加载器,则会进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器。
3、如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式
优点:
1、避免类的重复加载
2、保护程序安全,防止核心API被随意篡改

沙箱安全机制:防止恶意代码污染java源代码

比如我定义了一个类名为String所在包为java.lang,因为这个类本来是属于jdk的,如果没有沙箱安全机制的话,这个类将会污染到我所有的String,但是由于沙箱安全机制,所以就委托顶层的bootstrap加载器查找这个类,如果没有的话就委托extsion,extsion没有就到aapclassloader,但是由于String就是jdk的源代码,所以在bootstrap那里就加载到了,先找到先使用,所以就使用bootstrap里面的String,后面的一概不能使用,这就保证了不被恶意代码污染。

四、方法区
静态变量,常量,类信息(构造方法、接口定义),运行时的常量池,即static、final、Class、常量池存在方法区中,但是实例变量存在堆内存中与方法区无关。

五、堆和栈
1、堆区:
存储的全部都是对象,每个对象包含了一个与之对应的 class 类的信息。

一个JVM只有一个堆内存,它会被所有线程共享,堆中不存放基本数据类型和对象引用,它只存放对象本身,堆内存的大小是可以调节的。

类加载器读取了类文件后,一般会把类、变量、方法、常量放到堆中,保存所有引用类型的真实对象。

堆内存细分为三个区域:

新生区(伊甸园区 Eden Area);
养老区;
永久区;

在这里插入图片描述
GC垃圾回收主要是在伊甸园区和养老区;
假设内存满了,报OOM(OutOfMemory)异常,堆内存不够!

新生区:

类诞生、成长、死亡的地方;
伊甸园区:所有的对象都是从伊甸园区new出来的;
幸存者区(0,1)

永久区:
这个区域是常驻内存的,用来存放JDK自身携带的class对象,Interface元数据,存储的是Java运行时的一些环境或类信息,这个区域不存在垃圾回收,关闭VM虚拟就会释放这个区域的内存。

当一个启动类加载了大量的第三方jar包,TomCat部署了太多的应用,大量动态生成的反射类,不断的被加载,直到内存满就会出现OOM。

在JDK1.6之前:有永久代,常量池在方法区中;
JDK1.7:有永久代,但是慢慢退化了,形成了“去永久代”,常量池在堆中;
在JDK1.8之后:无永久代,常量池在元空间;

2、栈内存,主管程序的运行,生命周期和线程同步;线程结束,栈内存也就释放,对于栈来说不存在垃圾回收问题 ,一旦线程结束,栈就自动销毁。
栈中存放:8大基本类型+对象的引用+实例方法
3、栈和堆的区别:
栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。

JAVA对象在内存中实例化的过程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值