jvm
从问题引入
什么是jvm?
jvm在java6 7 8 有着什么变化
jvm常见的调优参数有哪些?
内存快照如何抓取?
怎么分析dump文件?
在java中 类加载器的认识
1 jvm存在的位置
2 jvm的体系结构
3 类加载器 类的初始化
我们要看的是这个类加载时候的一些个信息
3.1 加载器的种类
跟加载器 BOOT
扩展加载器 EXC
应用程序加载器 APP
4 双亲委派机制
BOOT>EXC>APP
在类请求类加载器加载的时候
会向上进行委托直至boot
如果能就加载,不能就返回上一级加载器加载
5 沙箱安全机制
个人理解就是限制了java代码运行的环境,只能在jvm中进行,而且不会干扰操作系统的运行
6 native 本地方法
比如线程的方法
有native 修饰的方法,都是java 没有的功能 需要调用本地方法
会进入本地方法栈执行
调用的就是本地方法 JNI java native interface
例如java 操作打印机
7 程序计数器
在单线程时候 这个东西是不需要的,因为即使没有,程序会按照指令执行下去,即使遇到分支跳转的情况,也会按照跳转到指定的指令处继续执行。
但是,现实的程序肯定都是多线程执行的,<mark style="box-sizing: border-box; background: rgba(229, 229, 229, 0); color: red; font-size: 20px;">jvm的多线程是通过cpu的时间片轮转来实现的</mark> 某个线程在执行的过程中可能会应为时间pain的耗尽而挂起,当他再次执行的时候呢,他就需要从挂起的地方开始执行,那么就是要通过程序计数器来记录字节码的执行位置,保证顺序的执行下去。
具有线程的独立性
占用的内存特别小
jvm中唯一不会内存溢出的一块
在native时候 程序计数器值为空
记录的事程序执行的字节码地址
8 方法区
方法区是被所有的线程共享的
所有字段、方法的字节码,还有一些各路的方法在这里(构造方法、接口代码)
-
就是在类加载之后,会将一些类的信息存放在方法区里边
<mark style="box-sizing: border-box; background: rgba(229, 229, 229, 0); color: red; font-size: 20px;">这个地方实在是不好理解</mark>
9 栈
运行的是程序执行时的方法,主管程序的运行,生命周期和线程同步。当线程结束,那么栈就会被释放,所以不会存在垃圾回收的问题。<mark style="box-sizing: border-box; background: rgba(229, 229, 229, 0); color: red; font-size: 20px;">是以线程为维度,堆是以进程为维度</mark>
栈 先进后出 后进先出
桶 新进先 后进后出 如队列
栈内存中:8种基本数据类型,对象的引用,实例的方法
-
还有一个栈帧的概念,每一个方法在执行的时候都会有两个帧
父帧
子帧
10 堆
一个jvm 中只有一个堆 进程级别
当类加载器加载一个类之后 会将真实的对象放到堆中,那么在无线的创建对象中,会oom OutOfMemoryError
-
分为
新生区
养老区
永久区
-
GC 垃圾回收机制 主要存在于新生区+养老区
轻GC
重GC
所有的对象创建后全部进入伊甸园,当满了之后 触发一次轻GC 活下来的进入幸存者区,当幸存者区也满了之后,意味着新生区满了,那么触发重GC,此时活下来的,流入老年区。
-
永久区
这个区域是常驻内存的,用来存放jdk自身携带的class对象,inteface元数据,存储java运行时的一些个环境。
不存在垃圾回收,程序关闭 就释放
11 堆内存调优
-Xms20m -Xmx20m -XX:+PrintGCDetails 这个是打出gc描述信息
-Xms10m -Xmx20m -XX:+HeapDumpOnOutofMemory 报了内存溢出 那么久dump日志
工具 MAT Jprofiler
分析dump文件 快速定位内存泄漏
获得堆中的数据
-
获得大的对象
1 在idea中安装Jprofiler 插件 主要就是生成对应日志分析文件
2 本地下载Jprofiler分析工具
3 启动添加打出oom的dump文件命令
4 将dump文件弄到Jprofiler 中分析
12 GC
作用域
在方法区和堆中进行
更确切的说是在:大部分时候在新生代 也会在幸存者区+老年区
GC逻辑 轻GC(Minor GC) 重GC(Full GC )
新创建的对象都会进入Eden区 就是伊甸园区
当Eden区满了之后 会进行轻GC 销毁没有继续引用的对象 部分不可销毁的对象进入幸存者1区 S0
当触发了轻GC后 不可销毁的进入S0 此时 S1是空的
当S0满了之后 会将还是没有销毁的对象放到S1里边(注意是全部),此时Eden触发轻GC 同样的存活下来对象也进入S1 S0空了
S0 和S1 会反复的复制存放(可以理解这个是剪切粘贴),但是当对象的反复存放超过15次 (-XX:MaxTenuringThreshold设置的值,默认是15) 那么会将对象放到老年代old
当轻GC的时候,存回的对象大于S0 的大小 会直接进入老年代
这就是著名的“停止-复制(Stop-and-copy)”清理法。
当对象存活了足够长的时间,进入老年代,但是当老年代空间也不足的时候,触发重GC
标记出存货对象,将所有存活对象向一端移动,保证内存连续
可通过-XX:+HandlePromotionFailure额外设置 -----标记整理算法
存放字节码、字符串常量池、静态变量、可持久化数据等
重GC也会销毁老年代中的可销毁对象
算法
GC有哪些算法:
标记清除法
标记整理,
引用计数器
复制算法