JVM--基础--03--内存区域--堆

JVM–基础–03–内存区域–堆


1、结构图

在这里插入图片描述

2、堆

在这里插入图片描述

  1. 堆中存的是对象:对象的大小是不可估计的,或者说是可以动态变化的
  2. 栈中存的是基本数据类型或者对象引用:一个对象引用大小是4btye。

2.1、特征

  1. 几乎所有的对象都存放在堆上。
  2. 堆是完全自动化管理的,通过垃圾回收机制,垃圾对象会被自动清理。
  3. 可能出现 OutOfMemoryError 异常。

2.2、栈到堆的关联过程

2.3、案例

SimpleHeap实例本身分配在堆中,描述SimpleHeap类的信息存放在方法区,main函数中的s1 s2局部变量存放在java栈上,并指向堆中两个实例。

3、内存溢出

当新建对象的时候,JVM没有内存可分配,且GC后还是没有内存可分配,那就会内存溢出

3.1、堆溢出代码案例

public class TestHeap {
	// 分配128Kb的内存给数组,方便堆内存溢出
	byte[] bis = new byte[128 * 1024];
 
	public static void main(String[] args) {
		List<TestHeap> list = new ArrayList<>();
		//增加堆内存
		while (true) {
			list.add(new TestHeap());
		}
	}
}
结果:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.fei.zhou.day1.TestHeap.<init>(TestHeap.java:8)
at com.fei.zhou.day1.TestHeap.main(TestHeap.java:14)

3.2、内存溢出的场景

  1. 内存中加载的数据量过于庞大,如一次从数据库取出过多数据
  2. 集合类中对对象的引用,使用完后未清空,使得JVM不能回收
  3. 代码中存在死循环或循环产生过多对象

3.3、怎么避免

  1. 修改JVM启动参数,直接增加内存。
  2. 检查错误日志,查看"OutOfMemory"错误前是否有其它异常或错误
  3. 对代码进行走查和分析

3.3.1、对代码进行走查和分析,

  1. 检查代码中是否有死循环或递归调用。
  2. 检查是否有大循环产生新对象实体。
  3. 检查对数据库查询中,是否有一次获得全部数据的查询,而没有使用分页。
  4. 检查List、MAP等集合对象是否有使用完后,未清除的问题。
    1. List、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。
  5. 尽早释放无用对象的引用
    1. 使用临时变量的时候,让引用变量在退出活动域后,自动设置为 null ,暗示垃圾收集器来收集该对象,防止发生内存泄露。
  6. 避免大量使用使用String
  7. 尽量少用静态变量,因为静态变量是全局的, GC 不会回收的
  8. 避免集合中创建大对象
    1. 因为 JVM 会突然需要大量内存,这时必然会触发 GC 优化系统内存环境
  9. 尽量运用对象池技术以提高系统性能
  10. 不要在经常调用的方法中创建对象

3.3.2、避免大量使用使用String

避免大量使用使用String,因为每一个 String 对象都得独立占用内存一块区域,所有应使用 StringBuffer

String str = "aaa";   
  
String str2 = "bbb";   
  
String str3 = str + str2;// 假如执行此次之后 str ,str2 以后再不被调用 , 那它就会被放在内存中等待 Java 的 gc 去回收 , 程序内过多的出现这样的情况就会报上面的那个错误 .

3.3.3、尽量运用对象池技术以提高系统性能

生命周期长的对象拥有生命周期短的对象时容易引发内存泄漏。
例如:大集合对象拥有大数据量的业务对象的时候,可以考虑分块进行处理,然后解决一块释放一块的策略。

3.3.3、不要在经常调用的方法中创建对象

可以适当的使用hashtable, vector创建一组对象容器,然后从容器中去取那些对象,而不用每次new之后又丢弃

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值