暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Java实战-浅谈内存存储模型

程序员的日记本 2020-08-17
821


Java中的内存存储

1、为什么要认识内存存储模型


认识内存模型能够帮助你在实际开发过程中设计合适的变量和类(了解Java的GC),明白并发模型(共享资源、锁、volatile、ThreadLocal),更好的分析内存溢出异常等。


2、怎么认识内存存储模型


认识Java的内存存储模型,从认识堆和栈存储的数据开始。




:局部变量中基础数据类型(含变量名和值)和自定义对象的引用变量都保存在栈中。

注意:此处的内存通过压栈和出栈进行管理,没有GC。


:GC处理的部分,主要保存new的对象和数组、类成员变量、String和类静态变量(JDK1.7开始将字符串常量区移到堆中了)。

当然在JVM不只有上面讲到的堆、栈,还有下面几种内存模型:
元空间(方法区)
:JDK1.8将方法区的数据移动到元空间,主要是类和类加载器的元数据信息(如类名、方法名、public、private等),而元空间是在本地内存中,因此理论上来说屏蔽了 PermGen这种内存溢出错误(JDK1.8以前是这些数据和static、字符串常量是存在永久代的)
程序计数器
:与指令执行相关;
本地方法栈
:与Native方法执行相关。


3、实战经验-从内存溢出错误定位代码


public class MemoryDivide {


static int a = 0; //堆空间
int b = 1; //堆空间


public void test(){
int a1 = 10; //栈空间
int b1 = 10; //栈空间


String s = "s" ; //堆空间

//引用变量存储在栈空间,对象在堆空间
Date date = new Date(System.currentTimeMillis());
}


/**
* 这个类我们可以分析出
* 1)、堆内存溢出
* 由代码可以看出出现堆内存溢出可能是某处创建了大量的对象,
     *      或者全局变量、静态变量,或者大量的String,
* 而没有被及时回收。
* 解决方式:单例类、将类作为参数传递、
     *      StringBuilder或者StringBuffer代替String等。
*
* 2)、栈内存溢出
* 由代码可以看出,有可能是某一方法中创建了大量的基本类型或者引用变量。
* 解决方法:根据实际情况而定,大部分情况下修改逻辑或者优化算法。
*
* 3)、在1.8以前还有一个永久代内存溢出,但是在1.8及以后的版本中基本不会出现了,
* 因为对应的内存区域已经被放到本地内存中了,
* 理论上只要本机内存够用,就不会溢出。
*/
}


文中所有代码均可以在线下载

https://gitee.com/wsyjiamian/JavaDiary.git

文章转载自程序员的日记本,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论