读书人

Java内存储器模型5

发布时间: 2013-10-08 15:18:04 作者: rapoo

Java内存模型5

3.本机内存[部分内容来源于IBM开发中心]  Java堆空间是在编写Java程序中被我们使用得最频繁的内存空间,平时开发过程,开发人员一定遇到过OutOfMemoryError,这种结果有可能来源于Java堆空间的内存泄漏,也可能是因为堆的大小不够而导致的,有时候这些错误是可以依靠开发人员修复的,但是随着Java程序需要处理越来越多的并发程序,可能有些错误就不是那么容易处理了。有些时候即使Java堆空间没有满也可能抛出错误,这种情况下需要了解的就是JRE(Java Runtime Environment)内部到底发生了什么。Java本身的运行宿主环境并不是操作系统,而是Java虚拟机,Java虚拟机本身是用C编写的本机程序,自然它会调用到本机资源,最常见的就是针对本机内存的调用。本机内存是可以用于运行时进程的,它和Java应用程序使用的Java堆内存不一样,每一种虚拟化资源都必须存储在本机内存里面,包括虚拟机本身运行的数据,这样也意味着主机的硬件和操作系统在本机内存的限制将直接影响到Java应用程序的性能。  i.Java运行时如何使用本机内存:  1)堆空间和垃圾回收  Java运行时是一个操作系统进程(Windows下一般为java.exe),该环境提供的功能会受一些位置的用户代码驱动,这虽然提高了运行时在处理资源的灵活性,但是无法预测每种情况下运行时环境需要何种资源,这一点Java堆空间讲解中已经提到过了。在Java命令行可以使用-Xmx和-Xms来控制堆空间初始配置,mx表示堆空间的最大大小,ms表示初始化大小,这也是上提到的启动Java的配置文件可以配置的内容。尽管逻辑内存堆可以根据堆上的对象数量和在GC上花费的时间增加或者减少,但是使用本机内存的大小是保持不变的,而且由-Xms的值指定,大部分GC算法都是依赖被分配的连续内存块的堆空间,因此不能在堆需要扩大的时候分配更多本机内存,所有的堆内存必须保留下来,请注意这里说的不是Java堆内存空间是本机内存。  本机内存保留本机内存分配不一样,本机内存被保留的时候,无法使用物理内存或者其他存储器作为备用内存,尽管保留地址空间块不会耗尽物理资源,但是会阻止内存用于其他用途,由保留从未使用过的内存导致的泄漏和泄漏分配的内存造成的问题其严重程度差不多,但使用的堆区域缩小时,一些垃圾回收器会回收堆空间的一部分内容,从而减少物理内存的使用。对于维护Java堆的内存管理系统,需要更多的本机内存来维护它的状态,进行垃圾收集的时候,必须分配数据结构来跟踪空闲存储空间和进度记录,这些数据结构的确切大小和性质因实现的不同而有所差异。  2)JIT  JIT编译器在运行时编译Java字节码来优化本机可执行代码,这样极大提高了Java运行时的速度,并且支持Java应用程序与本地代码相当的速度运行。字节码编译使用本机内存,而且JIT编译器的输入(字节码)和输出(可执行代码)也必须存储在本机内存里面,包含了多个经过JIT编译的方法的Java程序会比一些小型应用程序使用更多的本机内存。  3)类和类加载器  Java 应用程序由一些类组成,这些类定义对象结构和方法逻辑。Java 应用程序也使用 Java 运行时类库(比如?java.lang.String)中的类,也可以使用第三方库。这些类需要存储在内存中以备使用。存储类的方式取决于具体实现。Sun JDK 使用永久生成(permanent generation,PermGen)堆区域,从最基本的层面来看,使用更多的类将需要使用更多内存。(这可能意味着您的本机内存使用量会增加,或者您必须明确地重新设置 PermGen 或共享类缓存等区域的大小,以装入所有类)。记住,不仅您的应用程序需要加载到内存中,框架、应用服务器、第三方库以及包含类的 Java 运行时也会按需加载并占用空间。Java 运行时可以卸载类来回收空间,但是只有在非常严酷的条件下才会这样做,不能卸载单个类,而是卸载类加载器,随其加载的所有类都会被卸载。只有在以下情况下才能卸载类加载器
读书人网 >软件架构设计

热点推荐