A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 方建平 中级黑马   /  2012-11-25 22:46  /  2023 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

Java虚拟机中是如何管理堆内存的?对于内存的碎片化/空间不足等问题是如何处理的?垃圾是不是不到空间不足不会回收?哪位牛人可以介绍一下?

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

6 个回复

倒序浏览
Java内存分配:
ⅰ、寄存器:我们在程序中无法控制
ⅱ、栈区:
1、存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中;
2、每个栈中的数据都是私有的,其它栈不能访问;
3、栈区分为3个部分:基本类型变量区、执行环境上下文、操作指令区。
ⅲ、堆区:
1、存储的全部是对象,每个对象都包含一个与之对应的class信息;
2、Jvm 只有一个堆区(heap)被所有线程共享,存放用new产生的数据。
ⅳ、静态域:
1、静态域又称为方法区,被所有的线程共享。方法区包含所有的class和static变量。
2、方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。
常量池:存放常量
ⅴ、常量池:
1、常量池就是用来保存在编译阶段确定好了大小的数据;
2、除了包含代码中所定义的各种基本类型(如int、long等等)和对象型(如String及数组)的常量值(final)还包含一些以文本形式出现的符号引用,比如: 类和接口的全限定名; 字段的名称和描述符; 方法和名称和描述符。
3、在程序执行的时候,常量池会储存在Method Area,而不是堆中.
ⅵ、非RAM(随机存取存储器)存储:
1、硬盘等永久存储空间

对于内存的碎片化/空间不足等问题是如何处理的?垃圾是不是不到空间不足不会回收?
对于第一个问题还没有遇到过;
第二个问题,不是这样的,java中有垃圾回收机制,它可以自动回收堆中的垃圾。

希望对你有帮助。

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
其实对碎片化/空间不足等问题也是包括在垃圾回收机制里面的。一个是停止——复制,就是遇到垃圾了,停止程序将所有存活的对象从当前堆复制到另一个堆,没有复制的都是垃圾,对其进行回收  还有一个是标记-清理,就是先标记存活的对象,灯全部标记都完成时在清理没有被标记的对象垃圾。另一种就是两者结合叫做自适应技术,在前两者技术之间进行切换对垃圾进行回收

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
程序执行准备时,由JVM创建内存空间。程序运行中,由Java程序向java虚拟机申请内存,当内存空间超出初始内存时,java虚拟机再次向操作系统申请内存以供程序使用。当已申请的内存超过规定的最大内存空间,但是程序还需更多内存时,会出现内存溢出的错误。最大内存分配:方法区是64M,堆区是64M,栈区是1M.
内存空间逻辑划分为:方法区、堆区和栈区。
栈内存溢出会发生StackOverflowException错误。
堆内存溢出会发生OutOfMemoryError错误。

java中有GC垃圾回收机制,会自动回收堆内存中的垃圾。

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
垃圾自动回收,书上是这样记载的
当对象不再引用时,对象内存将被回收。
我觉得这对象回收的实现应该是在编译时期,如果下文没有了对该对象的引用,就插入调用系统回收内存的方法,实现垃圾回收。
这只是个人的想法。
当内存碎片化严重时,找不到大的连续内存空间时,JVM将调用操作系统的内存管理程序。
这也是个人的看法,如果你有更好地理解,欢迎回复。

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
首先要明白JAVA是在堆上分配对象,引用是存放在堆栈中的。
JAVA虚拟机有两种垃圾回收技术,第一种是停止-复制(stop-and-copy)。第二种是标记-清扫(mark-and-sweep)。
“停止-复制”依据的思想是:对于任何“活”的对象,一定能最终追溯到其存活在堆栈或静态存储区之中的引用,因此如果从堆栈和静态存储区开始,遍历所有的引用,就能找到所有“活”的对象。接着就会先暂停程序的运行(不属于后台回收模式),然后将所有存活的对象从当前堆复制到另一个堆,没有被复制的全部都是垃圾。
“标记-清扫”所依据的思想同样是从堆栈和静态存储区开始,遍历所有的引用,进而找出所有存活的对象。每当找到一个存活的对象,就会给对象设一个标记,这个过程中不会回收任何对象。只有全部标记工作完成的时候,清理动作才会开始。清理过程中,没有标记的对象将被释放。
而且这两种技术各有自己的优缺点,“停止-复制”需要更大的内存空间来进行复制,“标记-清扫”不需要复制,但清理后得到的空间是不连续的,若希望得到连续的空间同样需要再进行整理。因此JAVA虚拟机是根据内存实际情况在两种机制之间进行切换。

JAVA的垃圾回收器会帮你释放存储空间,但是“垃圾回收”并不保证一定会发生,如果JAVA虚拟机(JVM)并未面临内存耗尽的情形,它是不会浪费时间去执行垃圾回收以恢复内存的。

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
本帖最后由 Tokgo 于 2012-11-27 18:00 编辑

http://blog.csdn.net/lengyuhong/article/details/5953544
不如到这里看看,说得很全面。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马