class: java编译后的文件
JVM入口: 类加载器
JVM出口: 执行引擎,就是给操作系统发指令,操作系统再去控制硬件
本地方法栈: 就是java中的native方法(可以理解为java自己没法实现的),比如线程的Thread.start方法,要去调操作系统启动线程,也就是图中的本地方法接口,如果调用本地方法接口需要第三方类库支持时(比如安装游戏会有3D渲染DLL类库没有),就要用到图中的本地方法库。本地方法栈是线程私有的,如上面的例子,Thread一结束,方法也就结束,方法栈也就没了,内存回收,所以不用考虑GC
本地方法接口、本地方法库: 他们是操作系统的接口,Mac,windows,linux
java栈: 在线程创建时创建,这里有个压栈操作,如同往弹夹压子弹,把一个个方法压进去(先进后出,后进先出,后面有个例子),就比如执行一个线程,由几个方法串联完成, 它执行周期很短,线程私有,线程结束,内存回收,也不用考虑GC。
程序计数据:一个方法指向另一个方法的指针,就是来记录栈中方法执行的顺序。
方法区: Java虚拟机规范中定义方法区是堆的一个逻辑部分。方法区中存放已经被虚拟机加载的类信息(构造方法/接口定义)、常量、静态变量、即时编译器编译后的代码等。就理解是类的一个模板,new的实例在堆区,方法区是被所有线程共享的,所以在JVM停下来时,内存才被回收。
java堆 : 堆是用来存放对象的内存空间。几乎所有的对象都存储在堆中 ,垃圾回收的主要场所。 存放 new的对象、 实例变量
本地接口
方法区
程序计数器
队列
= 先进先出
栈
= 先进后出,后进先出 ,
弹夹
java栈例子
上面通俗的例子: 喝酒喝得差不多了,去厕所清洗内存,这就叫队列(先进先出),当喝得要吐了,就是栈(先进后出,后进先出)
内存溢出 java.lang.StackOverflowError
方法自己调自己,就是程序中循环递归调用了, 就相当于给弹夹一直压子弹
栈 +堆 +方法区的关系
堆:放的new 的对象
方法区: 放的类,比如加载过来的模板类User.class,
栈:八种基本类型(byte、short、int、long、float、double、boolean、char),及对象的引用 (就是指向new的对象)_
堆 Heap
伊甸区,就是刚new 的对象,GC后,还存活就进入0区(十之八九会被GC掉), 接着new的对象再加上上次0区的存留的,重新再GC,存后就进入1区, 只有经历15次GC的,才进去入养老区,能进养老区的对象说明是经常使用的,
如果养老区
经过FULL GC还是满的,那就挂了。养老区对象不会进永久区,它们是隔离的。
可以把上面的对象理解为上战场的士兵,比如第一批上战场士兵中有A战士,第一次GC后他还存活,就进0区,然后上第二批时,A战士也跟着上,如果还存活,就进入1区,如果这经历15次战斗还没被GC,就进入养老区。
物理划分
旧生代:
连接池,线程池
永久区
如自带的jar,一般是不同版本的jar太多,导致内容存溢出,现在用maven工程,不会出现了。