JVM Notes
/ / 点击 / 阅读耗时 6 分钟Java 技术体系包括以下几个组成部分:
- Java programming language
- Java Virtural Machine
- Class files
- Java api
- Third-party Java library
JDK = Java programming language + Java VM + Java API
JRE = JAVA SE API + JAVA VM
平台: Java Card, Java ME, Java SE, Java EE
Java 8, 引入Lambda支持
运行时数据区域
Program Counter Register
一块较小的内存,可以看做当前线程所执行的字节码的行号指示器,线程私有。
VM stack
和所属线程具有相同的生命周期,虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
如果线程请求的栈深度大于虚拟机所允许的深度将抛出StackOverflowError;
如果JVM Stack可以动态扩展,但是在尝试扩展时无法申请到足够的内存时抛出OutOfMemoryError。
Native Method Stack
和VM Stack 类似,区别在于该stack为虚拟机使用的Native方法服务,vm stack为虚拟机执行java方法服务。
Java Heap
所有线程共享
存放所有的对象实例(JIT编译器的发展导致不那么绝对)
Java 堆是垃圾收集器管理的主要区域。
如何确定垃圾?
- 引用计数法,即统计每个对象的引用数目,如果没有任何引用,则可以判定垃圾。存在问题是无法解决循环引用。
- 可达性分析,该方法的基本思想是通过一系列的“GC Roots”对象作为起点进行搜索,如果在“GC Roots”和一个对象之间没有可达路径,则称该对象是不可达的,不过要注意的是被判定为不可达的对象不一定就会成为可回收对象。
典型垃圾收集算法
- Mark-Sweep
- Copying
- Mark-Compact
- Generational Collection
Java Heap 根据垃圾回收机制,还可以进行细分,(新生代,老生代),更细致到 Eden, Survior
Method Area
线程共享,储存已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
内存无法满足时:OutofMemeoryError
Runtime Constant Pool
运行时常量池是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述等信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。
Direct Memoery
直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryError异常出现。
不会受到java堆大小的限制,但是会受到实际本机内存限制。