对象和内存溢出怎么处理

 我来答
动力节点
2016-06-07 · 口口相传的Java黄埔军校
动力节点
动力节点始于2009年,一家专注IT教育的培训机构,在全国各大城市设有直营校区,是中国软件研发人才一体化服务的倡导者,为解决当前软件开发技术飞速发展,专注培养面向互联网领域的IT高端软件人才
向TA提问
展开全部
1. 对象。
A.创建。首先检查指令的参数能不能在常量区找到类的符号引用,并检查这个类是否加载、解析和初始化过,如果没有就执行类的加载过程。其次是内存分配,类加载之后就知道要分配的内存大小,分配方法有两种,一种是指针碰撞,就是一块内存是使用过的,一块是未使用的,用一个指针分割,新分配的内存指针就向空闲的挪动,compact功能的虚拟机是用指针碰撞;另一种是空闲列表,就是一个列表记录空闲的内存块,不断更新列表,新分配的内存在列表中寻找一个合适大小的内存块,sweep功能的虚拟机是使用空闲列表。第三,在分配内存空间的时候,还要考虑并发性。有两个方法,一种是同步处理,如采用CAS和失败重试的方法;另外一种是把内存分配动作按照线程划分在不同的空间之中,每个线程在堆中预先分配一小块内存,本地线程分配缓冲TLAB,那个线程需要分配内存在那个TLAB上分配,只有TLAB用完了,才要同步锁定,重新分配。第四、对对象进行必要设置,比方说对象属于那个类,如何找到类的元数据信息和对象hashcode以及对象GC分代年龄等。
B.对象的内存布局。分为对象头、实例数据和对齐填充。对象头包括两部分,第一部分是存储对象自身信息,如hashcode,GC分代年龄,锁状态等;第二部分是类型指针,对象指向它的类的元数据的指针,虚拟机通过这个指针确定这是那个类的实例。
C.对象访问定位。两种方式,一种是句柄访问,句柄池有访问对象实例数据的指针和访问对象数据类型的指针。这个访问最大好处是reference是稳定的句柄池地址,对象改变都是改变句柄池里面的指针,而reference本身不动。另外一种就是直接指针,它有到对象类型数据的指针和实例数据。这个访问的好处是速度更快,节省了一次指针定位的开销。
2. 内存溢出OOM。
A.堆溢出。堆存放的是对象实例,只要不断创建对象,并且保证GC Root到对象有可大路径避免被垃圾回收清除掉对象,那么对象数量达到最大堆容量限制就会OOM。用内存映象分析工具,Eclipse Memory Analyzer分析一下。
B.虚拟机栈和本地方法栈溢出。分为两种,一种是如果线程请求的栈深度大于虚拟机所允许的最大深度,抛出StackOverFlowError异常;另一种是如果虚拟机在扩展栈时无法申请到足够内存空间,抛出OutOfMemoryError异常。可以减小最大堆和栈容量来获取更多的线程数量。
C.方法区和常量池溢出。会有额外提示 PermGen space。
D.本机直接内存溢出。这个Heap Dump文件看不到内存占用,但是如果有直接或简介使用了NIO,那有可能就是本机直接内存溢出了。
欣欣老师解惑
高粉答主

2016-06-07 · 关注我不会让你失望
知道顶级答主
回答量:7.1万
采纳率:58%
帮助的人:3312万
展开全部
内存溢出虽然很棘手,但也有相应的解决办法,可以按照从易到难,一步步的解决。
第一步,就是修改JVM启动参数,直接增加内存。这一点看上去似乎很简单,但很容易被忽略。JVM默认可以使用的内存为64M,Tomcat默认可以使用的内存为128MB,对于稍复杂一点的系统就会不够用。在某项目中,就因为启动参数使用的默认值,经常报“OutOfMemory”错误。因此,-Xms,-Xmx参数一定不要忘记加。
第二步,检查错误日志,查看“OutOfMemory”错误前是否有其它异常或错误。在一个项目中,使用两个数据库连接,其中专用于发送短信的数据库连接使用DBCP连接池管理,用户为不将短信发出,有意将数据库连接用户名改错,使得日志中有许多数据库连接异常的日志,一段时间后,就出现“OutOfMemory”错误。经分析,这是由于DBCP连接池BUG引起的,数据库连接不上后,没有将连接释放,最终使得DBCP报“OutOfMemory”错误。经过修改正确数据库连接参数后,就没有再出现内存溢出的错误。
查看日志对于分析内存溢出是非常重要的,通过仔细查看日志,分析内存溢出前做过哪些操作,可以大致定位有问题的模块。
第三步,安排有经验的编程人员对代码进行走查和分析,找出可能发生内存溢出的位置。重点排查以下几点:
 检查代码中是否有死循环或递归调用。
 检查是否有大循环重复产生新对象实体。
 检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。
 检查List、MAP等集合对象是否有使用完后,未清除的问题。List、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。
第四步,使用内存查看工具动态查看内存使用情况。某个项目上线后,每次系统启动两天后,就会出现内存溢出的错误。这种情况一般是代码中出现了缓慢的内存泄漏,用上面三个步骤解决不了,这就需要使用内存查看工具了。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式