胡倩萌的博客

胡萌萌的博客

JVM (Java虚拟机) 内存管理

Java不需要开发人员显式分配内存和回收内存,而是通过JVM来自动管理内存的分配和回收 ( 即GC )。这篇博文将用通俗易懂的方式来总结 JVM。

JVM的规范定义如下:
这里写图片描述

接下来我们分开来分析整个JVM。
1.JVM的内存管理:

这里写图片描述

如上图所示,Sun JDK 遵照JVM的规范,将内存划分为五部分,分别为:pc寄存器、JVM方法栈、本地方法栈、JVM方法区、JVM堆。

pc寄存器和JVM方法栈:

每个线程均会创建pc寄存器和JVM方法栈
pc寄存器占用的可能为cpu寄存器或者操作系统内存
JVM方法栈占用的是操作系统内存,JVM方法栈是线程私有
当方法运行完,其占用这两部分内存会自动释放。

本地方法栈:

本地方法栈用于支持本地方法的执行
存储了每个本地方法调用的状态
在Sun JDK 中,本地方法栈和JVM方法栈是同一个

JVM方法区:

存放了要加载的类的信息、类中的静态变量、类中定义的final类型的常量、类中的方法信息等。
方法区域是全局共享的
在Sun JDK 中方法区又称为持久代,默认最小值为16M,最大值为64M.
在一定条件下可以被GC.

JVM堆:
堆主要用于存储对象实例和数组值,Java中所有通过new创建的对象的内存都在堆中分配。由GC进行回收。
补充:老年代主要用来存放新生代中经过多次垃圾回收仍然存活的对象,例如缓存对象,新建的对象也有可能在老年代上分配内存(大对象或大的数组对象,且数组要保证无引用外部对象)。

关于堆的细节内容,请看我之前写的一篇博文:

Java GC、新生代、老年代

关于内存的分配问题:
Java对象所占有的内存主要是从堆上进行分配,堆是线程共享的,因此在堆上分配内存时需要加锁。当堆上空间不足时,会触发GC,若GC后空间仍然不足,则会抛出异常。

接下来,我们重点分析内存的回收:

JVM通过GC来回收堆和方法区中的内存
GC的基本原理是:
(1)先找到程序中不再被使用的对象
(2)回收这些对象所占用的内存
通常采用收集器的方式实现GC,主要的收集器有引用计数收集器和跟踪收集器。

1.引用计数收集器(分散式管理 ):
给每个对象设置一个引用计数器,当该对象被引用的时候,计数器的值加一,当计数器的值为0的时候,表示该对象没有被引用,即可以进行回收。
缺点:
(1)引用计数器需要在每次对象赋值时进行计数器的增减,有一定的消耗。
(2)引用计数器对于循环引用的场景没有办法进行回收。
所以,Java不使用这种收集器。
2.跟踪收集器 (集中式管理):

这里写图片描述

跟踪式收集器基于一定的条件触发,执行时需要从根集合扫描对象的引用关系,这会造成程序的暂停。

三种跟踪收集算法的缺点:
复制:成本是要增加一块新的内存以及进行对象的移动
标记--清除:会造成内存碎片
标记--压缩:不产生内存碎片但是对象移动成本高
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hqm12345qw/article/details/52354797
个人分类: java
上一篇java源码中的nio包和I/O模型
下一篇Hibernate(ORMapping) 上手实例与配置过程
博主设置当前文章不允许评论。

java内存管理白皮书

2016年02月16日 1.01MB 下载

Java虚拟机JVM:lib_j2re_test.rar

2008年12月02日 12.93MB 下载

没有更多推荐了,返回首页

关闭
关闭