Java虚拟机的基本结构
Paste_Image.png类加载子系统
类加载子系统负责从文件系统或者网络中加载Class信息,加载的类信息存放于一块被称为方法区的内存空间。除了类信息之外,方法区还可能存放运行时的常量池信息,包括字符串和数字常量。
Java堆
Java堆在虚拟机启动的时候建立,是Java程序最主要的内存工作区域。几乎所有的Java对象实例都存放在Java堆中。堆空间是一个程序的所有线程都共享的。
Java堆是完全自动化管理的,通过垃圾回收机制,垃圾对象会被自动清理,而不需要显示地释放。
Java堆根据垃圾回收机制的不同有可能拥有不同结构的堆。常见的是Java堆分为新生代和老年代。根据对象的存活时间。
Java栈
1
Java栈是一块线程私有的内存空间,和线程执行密切相关。线程的执行主要是函数调用,函数调用的数据都是通过Java栈来传递。
Java栈主要保存的是栈帧(局部变量表,操作数栈。帧数据区),每一次函数调用,都会有一个对应的栈帧被压入栈,每一个函数调用结束,都会有一个栈帧被弹出栈。当前正在执行的函数所对应的帧就是当前的帧(位于栈顶),保存当前函数的局部变量,中间运算结果等数据。
对于Java函数的返回方式不管是正常的return返回还是异常抛出,栈帧都会被弹出。
栈空间不足时,函数调用无法自然地继续执行下去。当栈深度大于线程的最大栈深度时,系统抛出StackOverflowError栈溢出。虚拟机通过参数-Xss来指定线程最大栈空间,决定函数调用的最大深度。
2.局部变量表
局部变量表保存函数的参数和局部变量,只在当前函数调用有效,随着栈帧的销毁,局部变量表也会随之销毁。
3.操作数栈
用于保存计算过程的中间结果,同时作为计算过程中的变量临时储存区。
4.帧数据区
在帧数据区保存着访问常量池的信息,方便程序访问程序常量池。
4.栈上分配
栈上分配是Java虚拟机提供的一项优化技术,对于线程私有的对象,其他线程不能访问的对象,可以将它们打散分配在栈上,而不是分配在堆上,分配在栈上的好处是可以在函数调用结束之后自行销毁,不需要垃圾回收器的介入。提高系统性能。
技术基础是逃逸分析,判断对象的作用域是否会逃逸出函数体。
方法区
java方法区和Java堆一样,是所有线程共享的内存区域,用于保存系统的类信息,类的字段,方法,常量池。方法区的大小决定系统可以保存多少个类,类太多会导致方法区溢出。
Java NIO库
允许Java程序使用直接内存,直接内存是栈外的,直接向系统申请的内存空间。通常,访问直接内存会快于Java堆。考虑系统性能,对于读写频繁的场合会考虑直接使用直接内存。直接内存的大小会直接受限于Xmx指定的最大堆大小,系统内存是有限的,受限于操作系统能给出的最大内存。
垃圾回收器
在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾。JVM的一个系统级线程会自动释放该内存块。垃圾回收意味着程序不再需要的对象是"无用信息",这些信息将被丢弃。当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用。事实上,除了释放没用的对象,垃圾回收也可以清除内存记录碎片。由于创建对象和垃圾回收器释放丢弃对象所占的内存空间,内存会出现碎片。碎片是分配给对象的内存块之间的空闲内存洞。碎片整理将所占用的堆内存移到堆的一端,JVM将整理出的内存分配给新的对象。
网友评论