99%的JVM调优都在堆中调优,java栈、本地方法栈、程序计数器不存在垃圾回收
3.类加载器作用:加载.class文件
- 虚拟机自带的加载器
- 启动类(根)加载器 Bootstrap ClassLoader 加载jt.jar包中的类
- 扩展类加载器 Extension ClassLoader 加载ext文件夹下所有.jar包中的类
- 应用程序加载器 Application ClassLoader 加载自己写的类
双亲委派机制:安全
- Application ClassLoader ---> Extension ClassLoader ---> Bootstrap ClassLoader
- 类加载器收到类加载的请求
- 将这个请求向上委托给父类加载器去完成,一直向上委托,直到启动类加载器(Bootstrap ClassLoader)
- 启动类加载器检查是否能够加载当前这个类,能加载就结束,使用当前的加载器,否则,抛出异常,通知子加载器进行加载
- 重复步骤4
Class Not Found异常就是这么来的
5.沙箱安全机制Java安全模型的核心就是Java沙箱(sandbox) ,
什么是沙箱?沙箱是一个限制程序运行的环境。沙箱机制就是将Java代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本
地系统资源访问,通过这样的措施来保证对代码的有效隔离,防止对本地系统造成破坏。
沙箱主要限制系统资源访问,那系统资源包括什么? CPU、内存、文件系统、网络。不同级别的沙箱对这些资源访问的限制也可以不
样。
所有的Java程序运行都可以指定沙箱,可以定制安全策略。
在Java中将执行程序分成本地代码和远程代码两种,本地代码默认视为可信任的,而远程代码则被看作是不受信的。对于授信的本地代
码,可以访问一切本地资源
6.Native- native :凡是带了native关键字的,说明java的作用范围达不到了,回去调用底层c语言的库!
- 会进入本地方法栈
- 调用本地方法本地接口 JNI (Java Native Interface)
- JNI作用:开拓Java的使用,融合不同的编程语言为Java所用!最初: C、C++
- Java诞生的时候C、C++横行,想要立足,必须要有调用C、C++的程序
- 它在内存区域中专门开辟了一块标记区域: Native Method Stack,登记native方法
- 在最终执行的时候,加载本地方法库中的方法通过JNI
- 例如:Java程序驱动打印机,管理系统,掌握即可,在企业级应用比较少
- private native void start0();
- 调用其他接口:Socket. . WebService~. .http
程序计数器: Program Counter Register
每个线程都有一个程序计数器,是线程私有的,就是一个指针, 指向方法区中的方法字节码(用来存储指向像一条指令的地址, 也即将要执
行的指令代码),在执行引擎读取下一条指令, 是一个非常小的内存空间,几乎可以忽略不计
8.方法区 method area方法区是被所有线程共享的,所有的字段和方法字节码,以及一些特殊方法,如构造函数,接口代码也在此定义,简单说,所有定义方法
的信息都保存在该区域,此区域属于共享空间
存储内容:static、final、.class、常量池
9.栈 stack栈:先进后出
队列:先进先出( FIFO : First Input First Output )
栈内存:主管程序的运行,生命周期和线程同步
线程结束,栈内存也就是释放,对于栈来说,不存在垃圾回收问题
一旦线程结束,栈就Over!
栈满了: StackOverflowError
存储:8大基本类型 + 对象引用 + 实例的方法
10.三种jvm-
HotSpot 我们用的
-
JRockit BEA
-
J9 vm IBM
Heap,一个JVM只有一个堆内存,堆内存的大小是可以调节的。
堆内存划分:
-
新生区(New):伊甸园(Eden)、幸存0区(from)、幸存1区(to)。对象在这里诞生、成长、甚至死亡
- 伊甸园(Eden):所有对象都是在Eden区new出来的。
-
老年区(Old):
-
永久区(Perm):jdk1.8以后,叫元空间(方法区在这里,常量池在方法区里)。这个区域是常驻内存的,用来存放jdk自身携带的
class对象。
伊甸园满了就触发轻GC,经过轻GC存活下来的就到了幸存者区,幸存者区满之后意味着新生区也满了,则触发重GC,经过重GC之后
存活下来的就到了养老区。
堆内存满了:OutOfMemoryError
12.堆内存调优OOM:
-
尝试扩大堆内存看结果
-
分析内存,看一下哪个地方出了问题(专业工具)
Xms1024m Xmx1024m -XX:+PrintGCDetails
在一个项目中,突然出现了OOM故障,那么该如何排除?研究为什么出错
jprofiler作用:
-
分析dump内存文件,快速定位内存泄露
-
获得堆中的数据
-
获得大的对象
轻GC
重GC
引用计数法:记录每个对象的引用次数,长时间没有被引用的对象就被清除掉。
复制算法:
好处:没有内存碎片
坏处:浪费内存空间,多了一半to空间永远是空的。
复制算法最佳使用场景:对象存活度较低的时候 -> 新生区
标记清除算法:
优点:不需要额外的空间。
缺点:两次扫描,严重浪费时间,会产生内存碎片。
标记压缩:
标记 -> 清除 -> 压缩