2.程序计数器 是指当前线程所执行字节码的行号指示器 比如if 循环 抛异常 等都需要程序计数器
如果线程执行java方法 程序计数器记录的是虚拟机字节码指令的地址 如果线程执行native方法时程序计数器记录的值为空 程序计数器是java虚拟机唯一一个没有规定内存溢出的区域
3.虚拟机栈和本地方法栈 虚拟机栈主要是为虚拟机执行的java方法服务 本地方法栈主要是未虚拟机使用的native方法服务
4.GC的分代收集算法 分为年轻代和老年代 年轻代才有复制算法 eden from to
当eden区满了 会启动年轻代的垃圾回收将还在被引用的对象复制到from 如果edan再次满了
form区会将还在被引用的对象复制到to from和to是一个循环复制 当from和to都满了则复制到
老年代区去 采用的标记清理和标记整理算法 老年代内存满了 则进行大扫除 FUll GC
FUll GC过多会影响到系统性能 合理分配年轻代和老年代的内存大小 尽量减少FUll GC操作
根据不同场景 选择合适的垃圾收集器
5.堆 是被所有线程共享的内存区域 java虚拟机启动时创建 主要存储对象实例 也是垃圾收集器
管理的重要内存区域 方法区是存储已被虚拟机加载的类信息 很少会被垃圾回收 一般收集常量池和
对类型的卸载
6.引用方式二种 使用句柄 和使用直接指针
使用句柄 存储了稳定的句柄地址 对象被移动了 只会改变句柄中实例数据的指针 reference本身不需要修改
使用直接指针 减少了一次指针定位的时间开销 提高效率
7.如果建立过多的线程导致栈溢出 可以通过减少堆内存和减少每个线程分配的栈容量增加线程数
8.怎么判断对象是否存活 不是用引用计数算法(对于对象相互引用的情况不可行) 用根搜索算法
当GC roots 到对象不可达的时候代表就可以回收了
9.对象的finalize方法只会被系统调用一次
10.方法区的无用类的判断
第一 该类的所有实例都被回收了 也就是堆中不存在该类的任何实例对象
第二 该类的加载器ClassLoader已经被回收了
第三 该类的java.lang.Class 不在任何地方引用 任何地方不存在反射引用该类的方法
11.可以设定进入老年代的对象最大年龄阀值 max 对象每经过一次Minor GC 对象年龄加一
对象年龄超过阀值则就进入老年代 或者是 survivor区当相同年龄的对象内存在survivor区内存的一半则将等于或者大于这个年龄的进入老年代
12.java自带一些命令和工具查看java虚拟机内存使用情况
jps命令 获取到虚拟机的进程号pid
jinfo命令 获取到java虚拟机信息
jstat命令 获取到java虚拟机统计信息监控工具 就是堆栈和永久代等的使用情况
jmap命令 获取到java虚拟机 堆内存的使用情况 比如新生代和老年代
jstack命令 获取到java虚拟机栈内存的使用情况
13.内存管理工具 jconsole和VisualVM(多合一故障处理工具)
jconsole启动jdk中bing中jconsole.exe可执行文件就可以使用
VisualVM需要安装插件
14.正向代理和反向代理 正向代理 客户端和代理在同一网 反向代理 代理和服务器在同一个网
15.Serial收集器和CMS收集器 收集器不是万能需要更加具体的情景采用不同的收集器
Serial收集器采用的单线程执行 停止其他的工作 只执行垃圾收集
ParNew收集器采用的多线程执行 停止其他的工作 和Serial类似 就是可以多线程执行
CMS收集器采用的和工作线程并发执行垃圾收集 低停顿 解决GC停顿时间长的问题
G1收集器是在CMS收集器上的优化 可以控制停顿时间
Paralel Scavenge收集器控制吞吐量
一般新生代采用Serial和ParNew收集器 老年代采用CMS收集器
16.有11G垃圾而且还有大对象 导致服务器每隔十几分钟停顿十几秒 怎么解决呢
服务器采用6个32位JDK的逻辑集群 每个进程分配2G 总共12G 建立一个Apache服务作为前端
均衡代理访问门户
17.JBossCache 和 MemCached 分布式缓存架构
JBossCache采用的每个集群服务器都有公共的缓存 这样相当于一个服务器的缓存需要同步其他的服务器的缓存 代价大
MemCached采用的互不通讯的方式 有一个公共的服务器管理所有集群服务器的缓存
18.堆 虚拟机栈和本地方法栈(线程死锁和直接内存) 进程(Runtime.getRuntime().exec())
19.生产者和消费者模式解决不断创建线程导致的jvm内存不足还一直重启的问题
20.类在虚拟机的整个生命周期 加载 验证 准备 解析 初始化 使用 卸载
21.tomcat如何规划用的类库和加载器? (双亲委派模型 启动类加载器 扩展类加载器 应用程序加载器 用户自定义加载器)
common/ tomcat和所有的web应用程序共同使用 common类加载器
server/ tomcat使用 所有的web应用程序不能使用 catalina加载器
shared/ tomcat不能使用 所有的web应用程序使用 shared加载器
WEB-INF/ 当前应用程序使用 其他应用程序和tomcat不能使用 webApp加载
22.javac编译器是将java文件编译成字节码的class文件 加载器则是将将字节码的class文件加载到JVM上 动态代理模式采用生成字节码的方式实现
23.类加载器原则:委托 单一 可见性
委托:application加载器委托给Extention加载器 Extention加载器再委托给Boostsrap加载器(再向下寻找)
可见性 父类的加载的类子类可见 子类的加载的类父类不可见
单一性 父类加载的类 子类不能重复加载
24.java泛型相比C语言的泛型定义是不一致的 java的泛型可以说是伪泛型
java泛型实现原理 采用Object 进行强制类型转换 在编译是存储的是泛型T 所以会出现不同的泛型的List集合做为单参无法重载 在运行时进行强制类型转换 缺点是容易出现ClassCastException异常
25.java虚拟机采用基于计数的热点探测 检查线程的栈顶经常出现的代码 统计热点代码
26.线程安全的volatile修改的变量 被一个线程修改了会被及时刷新到变量中被其他线程可见
synchronized lock
27.锁优化方案 锁加粗 消除锁 偏向锁 轻量级锁 自旋锁和自适应锁 提高因为加锁的降低的效率