我们知道,每个应用程序都需要OS分配一定的内存才能运行。最大可分配的内存受OS的限制,不同的OS对进程所能访问虚拟内存地址区间直接影响对于应用内存的分配,32位的操作系统通常最大支持4G的内存寻址,而 Linux一般为3G,Windows为2G。
那么,Java是如何管理OS分配给的内存的呢?
这就要提到Java的内存管理中的两个东东:堆(Heap)和栈(Stack)。
1. 堆(Heap)
Heap是内存数据区,是存储对象实例的地方(即使用new创建的对象)。
(1)优点:可以动态地分配内存大小,生存期也不必事先告诉编译器。
(2)缺点:由于要在运行时动态分配内存,存取速度较慢。
(3)回收方法:因为是在运行时动态分配内存的,Java的垃圾收集器GC会自动收走这些不再使用的数据。
2. 栈(Stack)
Stack是内存指令区,是存储基本数据类型、指令代码、本地变量、常量、对象的引用地址的地方。方法属于指令,保存在stack中。对象实例在heap中分配好以后,需要在stack中保存一个4个字节的heap内存地址,用来定位该对象实例在Heap中的位置。
(1)优点:存取速度比Heap要快,仅次于寄存器,而且Stack中的数据可以共享,比如每个线程都有自己的Stack,线程之间可以共享数据。
(2)缺点:存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。
(3)回收方法:Stack的数据结构是先进后出(FILO),能够自动释放空间,不需要Java的垃圾收集器GC。
3. Native Heap Memory
OS分配的内存并不会全部给JVM的Java Heap使用,它主要会分成三部分:Java Heap,Native Heap,载入资源和类库等所占用的内存。由此可见,Native Heap和 Java Heap大小配置是相互制约的,哪一部分分配多了都可能会影响到另外一部分的正常工作。
Native Heap Memory是JVM内部使用的Memory,这部分的Memory可以通过JDK提供的JNI的方式去访问,这部分Memory效率很高,但是管理需要自己去做,如果没有把握最好不要使用,以防出现内存泄露问题。可以在JVM启动时候增加-verbose:jni参数来观察Native Heap Memory。
没有评论:
发表评论