最近在看java虚拟机,目的是更好的运维和监控java程序,所以我的理解角度不是程序开发员而是运维人员,下面是一些看书总结,部分内容摘抄自《深入浅出java虚拟机》。
=================================================================================================================================
java虚拟机运行时,大致会把内存分为线程私有区域和共有区域,私有区域随着线程生而生,随着线程销毁而销毁。
程序计数器
这个区域是所有区域内唯一一个不会发生OutOfMemoryError的区域,程序计数器的大致作用就是:java虚拟机是多线程机制,工作的时候需要多线程之间轮换,而程序计数器就是用来记录切换之前正在执行的指令的地址。
虚拟机栈
这个区域描述的是java方法执行的内存模型,也就是存储方法(Native方法除外)的局部变量表,动态链接等关于方法信息。这个区域一般是可以动态扩展的(不过有可能会是固定的),当动态扩展申请不到内存的时候,就会发生OutOfMemoryError异常。
本地方法栈
这个区域的功能和虚拟栈差不多,只不过他是为Native方法服务的,这个区域也会发生内存泄漏和内存溢出异常。
堆
这个区域是jvm内存区域里面最大的一块,也是发生垃圾回收的主要区域,每个线程启动的时候都会在这个区域里面预分配一小块区域用于存放对象实例,也许不久的将来这不会成为“绝对”。由于垃圾回收是分代回收的,所以这个区域分为年轻代和老年代,年轻代又分为:Eden空间,to survivor ,from survivor区域。这个区域可以通过参数调整大小,可以固定也可以动态。
方法区
这个区域主要用来存放被虚拟机加载的类信息 变量 静态变量 等数据信息,也就是俗称的“永久代”,这个区域很难有好的垃圾回收成绩。
直接内存区
这个区域需要格外注意一下,他不属于运行时区域,但是在NIO类的基于通道域缓冲区I/o方式中,会在java堆外分配内存,所以在分配主机内存的时候要考虑这块区域,合理分配大小,避免堆外空间不足,发生内存溢出。