JVM 虚拟机
JVM加载类机制
- JVM类加载分为五个阶段:加载->验证->准备->解析->初始化 (->使用->卸载)。
- JVM提供了3种类加载器:启动类加载器、扩展类加载器和应用类加载器。
- 双亲委派机制核心:保障类的唯一性和安全性。
- 打破双亲委派机制:自定义加载器继承ClassLoader类,重写loadclass方法和findclass方法。
- 双亲委派类加载机制的类加载流程:
JVM中一次完整的GC流程是怎样的
- 当创建一个新对象时,就需要为该对象申请内存空间。
- 首先会判断Eden区是否有内存空间,如果此时有内存空间,则直接将新对象保存在Eden区
- 但是如果此时Eden区的内存空间不足,那么会自动执行一个Minor GC操作,清理之后会继续判断Eden区的内存空间是否充足,如果内存空间充足,则在Eden区进行新对象的空间分配。
- 如果执行了Minor GC之后发现Eden区的内存依然不足,那么这个时候会进行Survivor区判断,如果Survivor区有剩余空间,则将Eden区的部分活跃对象保存在Survivor区。随后继续判断Eden区的内存空间是否充足,如果充足,则在Eden区进行新对象的空间分配。
- 如果此时Survivor区也已经没有内存空间了,则继续判断老年区,如果此时老年区空间充足,则将存活区中的活跃对象保存到老年代,而后Survivor区就会存现有空余空间,随后Eden区将活跃对象保存在Survivor区之中,而后在Eden区进行新对象的空间分配。
- 如果这个时候老年代也满了,那么这个时候将产生Major GC(Full GC),进行老年代的内存清理。
- 如果老年代执行了Full GC之后发现依然无法进行对象的保存,就会产生OOM异常“OutOfMemoryError”。
什么时候触发Full GC
- 老年代空间不足(碎片,或者分配不足)。
- 在执行CMS GC的过程中同时有对象要放入老年代,而此时老年代空间不足(concurrent mode failure)。
- minor GC后晋升到老年代的平均大小大于老年代的空间。
- 主动触发Full GC(System.gc() || jmap -histo:live [pid]) 来避免碎片问题。
JVM内存泄漏
- 产生原因:持有对象的强引用,且没有及时释放,进而造成内存单元一直被占用。
- 解决:提高程序的健壮型,因为内存泄露是纯代码层面的问题。
- 和内存溢出的联系:1.内存泄露会最终会导致内存溢出。2.内存泄露可以通过完善代码来避免,内存溢出可以通过调整配置来减少发生频率,但无法彻底避免。
当出现内存溢出,怎么排错
- 产生原因:JVM内存过小、程序不严密,产生过多的垃圾。
- 首先控制台查看错误日志。
- 然后使用jdk自带的jvisualvm工具查看系统的堆栈日志。
- 定位出内存溢出的空间:堆,栈还是永久代(jdk8以后不会出现永久代的内存溢出)。
- 如果是堆内存溢出,看是否创建了超大的对象。
- 如果是栈内存溢出,看是否创建了超大的对象,或者产生了死循环。
Tomcat
Tomcat性能调优
- Tomcat调优主要从四个方面考虑:1.吞吐量、2.Responsetime、3.Cpuload、4.MemoryUsage。
- JVM调优
MySQL中存储引擎
- MyISAM存储引擎:MyISAM基于ISAM存储引擎的扩展。它是在Web、数据仓储和其他应用环境下最常使用的存储引擎之一。MyISAM拥有较高的插入、查询速度,但不支持事务。
- InnoDB存储引擎:InnoDB是事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键,InnoDB是默认的MySQL引擎。
- 区别:
- 一是主索引的区别,InnoDB的数据文件本身就是索引文件。而MyISAM的索引和数据是分开的。
- 二是辅助索引的区别:InnoDB的辅助索引data域存储相应记录主键的值而不是地址。而MyISAM的辅助索引和主索引没有多大区别。
三个范式是什么
- 第一范式:字段是最小的的单元不可再分。
- 第二范式:满足第一范式,表中的字段必须完全依赖于全部主键而非部分主键。
- 第三范式:满足第二范式,非主键外的所有字段必须互不依赖。
简单说一说drop、delete与truncate的区别
- Delete用来删除表的全部或者一部分数据行,执行delete之后,用户需要提交(commmit)或者回滚(rollback)来执行删除或者撤销删除, delete命令会触发这个表上所有的delete触发器; <