【理解JVM】JVM内存管理(1)

来源:互联网 发布:淘宝勾针玩偶 编辑:程序博客网 时间:2024/04/29 12:25

1.1 内存结构

 

1、两个子系统:Class loader子系统和Execution engine(执行引擎)子系统

(1)Class loader子系统

根据给定的全限定名类名(如java.lang.Object)来装载class文件的内容到Runtime data area中的method area(方法区域)

(2)Execution engine子系统

执行classes中的指令。任何JVM specification实现(JDK)的核心都是Execution engine

 

2、两个组件:Runtime data area(运行时数据区域)组件和Native interface(本地接口)组件

(1)Native interface组件

与native libraries交互,是与其它编程语言交互的接口。当调用native方法的时候,就进入了一个全新的并且不再受虚拟机限制的世界。

(2)Runtime Data Area组件——JVM的内存

Heap(堆):一个Java虚拟实例中只存在一个堆空间,用于存储对象实例及数组值,可以认为Java中所有通过new创建的对象的内存都在此分配,其大小可以通过-Xmx和-Xms来控制。

 

堆被划分为新生代和旧生代,新生代又被进一步划分为Eden和Survivor区,Survivor由S0和S1组成。新建的对象都是用新生代分配内存;旧生代用于存放新生代中经过多次垃圾回收仍然存活的对象


Method Area(方法区域):被装载的class的信息存储在Method area的内存中。当虚拟机装载某个类型时,它使用类装载器定位相应的class文件,然后读入这个class文件内容并把它传输到虚拟机中。在Sun JDK中这块区域对应 Permanent Space,又称永久代。

可能抛出异常: java.lang.OutOfMemoryError: PermGen space

 

Java Stack(java的栈):虚拟机只会直接对Java stack执行两种操作:以帧为单位的压栈或出栈,Java栈为线程私有,当方法运行完毕,对应的栈帧所占用内存自动释放。可以通过-Xss来指定大小。

可能抛出异常: StackOverflowError

 

Program Counter(程序计数器):每一个线程都有它自己的PC寄存器,也是该线程启动时创建的。PC寄存器的内容总是指向下一条将被执行指令的地址。

Native method stack(本地方法栈):保存native方法进入区域的地址,用于支持native方法的执行,存储了每个native方法调用的状态。当一个线程调用本地方法时,它就不再受到虚拟机关于结构和安全限制方面的约束,它既可以访问虚拟机的运行期数据区,也可以使用本地处理 器以及任何类型的栈。

 

1.2 内存分配

1、堆(Heap)和非堆(Non-heap)内存

堆:就是Java代码可及的内存,是留给开发人员使用的。

非堆:就是JVM留给自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。


2、堆内存分配

JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC后调整堆的大小。


3、非堆内存分配

JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。


4、JVM内存限制(最大值)

首先JVM内存限制于实际的最大物理内存,假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了。

0 0
原创粉丝点击