Skip to content

Latest commit

 

History

History
98 lines (68 loc) · 5.28 KB

File metadata and controls

98 lines (68 loc) · 5.28 KB

垃圾回收机制

​ 寻找需要回收的对象,垃圾回收算法 ​ 1.引用计数器 ​ 2.引用可达法 ​ 通用的分代垃圾回收机制: ​ 根据不同的生命周期将对象划分为 年轻代,年老代,持久代。 ​ JVM将堆内存划分为 Eden Survivor Tenured/Old空间 ​ 年轻代在 Eden Survivor1 Survivor2 年老代在 Tenured/Old 持久代在方法区 ​ 垃圾回收过程: ​ 1.新创建的对象,绝大多数都会存储在Eden中 ​ 2.当Eden满了(达到一定比例)不能创建新对象,则触发垃圾回收,通过算法将无用对象清理掉 ​ 然后剩余对象复制到某个Survivor,如Survivor1,同时清空Eden区 ​ 3.当Eden再次满了,会对Survivor1进行清理,然后将剩余的对象存到另一个Survivor中,如Survivor2 ​ 同时将Eden区中不能清空的对象,也复制到Survivor2中,保证Eden和Survivor1,均被清空 ​ 4.重复多次(默认15次)Survivor中没有被清理的对象,则会复制到老年代Tenured/Old ​ 5.当Tenured/Old满了,则会触发一个一次完整地垃圾回收(FullGC),清理年轻代,老年代,成本较高,会对系统性能产生影响

开发中容易造成内存泄漏的地方:

​ 1.创建大量无用对象 ​ 2.静态集合类的使用,静态集合类所包含的对象不能被释放 ​ 3.各种连接对象(IO流对象,数据库连接对象,网络连接对象)未关闭 ​ 4.释放对象时没有删除对应当监听器

JVM内存划分

java虚拟机内存可以分为三个区域:栈stack、堆heap、方法区method area 栈stack 1.jvm为每个线程创建一个栈,,栈中存放该线程执行方法的信息(实际参数、局部变量) 2.是描述方法执行的内存模型,每个方法被调用都会创建一个栈帧(存储局部变量、操作数等) 3.所以栈是私有的,不同线程不能共享 4.存储特点是“先进后出,后进先出” 5.系统自动分配的连续内存空间,速度快 堆heap 1.堆用于存储创建好的对象和数组(数组也是对象) 2.JVM只有一个堆,被所有线程共享 3.堆是一个不连续的内存空间,分配灵活,速度慢 方法区 1.JVM只有一个方法区,被所有线程共享 2.方法区实际也是堆,只是用于存储类,常量相关的信息 3.用于存放程序中永远不变或唯一的内容,(类信息[Class对象],静态变量,字符串常量等)

JVM启动的时候会根据当前线程在内存中创建一个栈,在内存中创建方法区并加载 字节码文件、静态变量、静态方法、字符串常量 然后在静态方法中寻找main方法,开始程序的入口,并为main方法在栈中创建一个栈帧,存储局部变量、操作数、方法出口等

JVM核心机制

​ 类加载机制 ​ 加载 ​ 将class文件字节码内容加载到内存中,并将class文件中的静态数据结构转换成方法区中的运行时数据结构,就是在方法区生成一个运行时数据(方法区类数据) ​ 在堆中生成一个代表这个类的java.lang.Class对象,作为方法区类数据的唯一访问入口, ​ 链接 ​ 验证 ​ 确保加载的类信息符合JVM规范,没有安全方面的问题 ​ 准备 ​ 正式为类变量(static变量)分配内存并设置类变量初始值(这里的值是数据类型默认值)的阶段,这些内存都将在方法区中进行分配 ​ 解析 ​ 虚拟机常量池内的符号引用替换为直接引用的过程 ​ 初始化 ​ 初始化阶段是执行类构造器()方法的过程,类构造器()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块中的语句合并产生的 ​ 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化 ​ 虚拟机会保证一个类的()方法在多线程环境中被正确加锁和同步 ​ 当访问一个java类的静态域时,只有真正声明这个域的类才会被初始化

动态编译

​ JavaCompiler
​ JavaCompiler compiler=ToolProvider.getSystem.javaCompiler(); ​ int result=compiler.run(null,null,null,sourceFile); ​ 第一个参数:为java编译器提供参数 为InputStream ​ 第二个参数:得到Java编译器输出的参数,为OutputStream ​ 第三个参数:接收编译器的错误信息,也是输出流 ​ 第四个参数:可变参数,(是一个String数组)能传入一个或多个Java源文件 ​ 返回值:0表示编译成功,非0表示编译失败 字节码操作 Javassist

对象头大小

Mark Word:标记位4字节,类似轻量级锁标记位,偏向锁标记位等。2. Class对象指针:4字节,指向对象对应class对象的内存地址。3,对象实际数据:对象所有成员变量。4,对齐对齐填充字节,按照8个字节填充。Integer占用内存大小, 4+4+4+4-16字节。