jvm之运行时数据区
什么是jvm?
jvm是jdk中的一个基础架构,它的存在主要是运转java程序的,当前在开发当中我们只有真正的去理解jvm才能写出高性能的系统,我们都知道Windows与Linux系统最终执行的机器码是不一样的,例如 windows中可能是010101 Linux中则是101010 那么我们的java系统是可以部署在不同的操作系统之上,其中jvm帮助了我们处理了不同系统的机器码转化,从而从软件层面解决屏蔽了不同系统的问题,也就是我们经常说的java跨平台
jvm都分为什么?
1类加载
2运行时数据区(本章的内容) 需要掌握的
3执行子系统
什么是运行时数据区?
运行时数据区就是jvm在运转过程中 处理数据的区域,运行时数据区又分为以下几个区域,堆,方法区(元空间),jvm虚拟栈,本地方法栈,程序技数器,
什么是栈呢?(线程私有)
栈是用来保存局部变量的,栈本身是一种数据结构,是一个容器,有着先进后出的特点,其中我们的栈又包含多个栈桢,由多个栈桢组成,每个栈桢相对于我们java中的一个方法,栈桢又可以细分为 局部变量表,操作数栈,动态链接,返回地址,以下这张图你只要是搞java的就一定能看懂,
总结:局部变量表存储着我们java8大基础数据类型对应的字节变量,在我们开发当中,要避免栈内存溢出,例如无限递归循环,也要避免使用递归处理数据,因为每执行一次方法 就需要在桢内存开辟新的栈桢空间,
什么是本地方法栈?(线程私有)
本地方法栈是我们java借助C++提供的一些特性来完成一些功能,操作执行步骤与我们的jvm的栈是一样的,这里不做多解释,比例在java中使用native来修饰的字段,其都由本地方法栈来处理,
程序计数器有是什么?(线程私有)
说到程序计数器,就的先了解字节码文件,我们的java文件编译后的class文件,其中java 一行代码,会分解成多行字节码,每行字节码对应着行号,我们程序计数器会记录这些行号和对应的地址,单线程还好,多线程执行的时候可能会把一个方法分为很多块去执行,所以需要记录当前执行的行号,以免下次get到cpu资源了不知从哪执行,
什么是堆?(公共)
堆里面存放的都是我们创建的对象。堆分为 新生代区,老年代区,为什么堆会分代?
1,如果没有分代,所有的对象都在一块,GC的时要找到哪些对象是没用的,这样就会对堆的所有区域进行扫描。而我们的很多对象都是朝生夕死的。朝生夕死的意思是百分之90的对象子创建完不久就会死掉,如果分代的话,把新创建的对象放到某一地方,当GC的时先把这块存“朝生夕死”对象的区域进行回收,这样就会腾出很大的空间出来,以下借助了一张网图 新生区分为 Eden ,From ,To,在Eden存活下来对象会被存放到From中->To--TenuredSpace老年代
2,,jvm给我们提供了几种垃圾回收的处理机制,各有各的优点,分代也是为了充分发挥出他们各自的优点,1表记性清除法(缺点存在内存碎片)2表记性清楚整理算法3可达性分析算法3复制算法,
标记清楚算法:如果当前对象被引用过一次则对应的标识+1 引用失效则对应的标识-1 但最终为0 成为垃圾对象,清楚之后的空间不会整理,产生垃圾碎片,并且两个对象互相引用是检查不出来的
标记清楚整理算法:与上执行一样 只是对清楚之后的空间进行了整理,不会有垃圾碎片的存在
可达性分析:gcRoots 把我们的对象引用 链接起来,被我们的主程序主杆链接的则不是垃圾对象,否则则是垃圾对象,有四类称之为gcRoots主杆,1局部变量引用的对象2本地方法栈引用的对象,3静态变量引用的对象4常量引用的对象 他们被称之为gcRoots
复制算法:开辟2倍的空间把存货下来的对象copy移到新的空间
方法区(元空间)又存储着什么?(公共)
java中的静态变量,和常量,是公共的资源,