jvm模型与多线程关系以及三种内存溢出解决

JVM模型

局部变量:在方法内创建的变量
成员变量:类中创建的变量

方法区(线程不安全):①类(class)②静态变量(static变量)③静态方法④常量和⑤成员方法。
(线程不安全):对象(包括局部变量中的对象变量),对象的成员变量(包括基本类型变量)
(生命周期同它的线程周期,线程独有,线程安全):局部变量中的基本类型变量,对象引用

方法区只是一个概念,每一个不同的jvm提供商实现的方式不一样,我们一般用的是Sun公司的HotSpot。它在Jdk1.2-1.6用永久代来实现这个概念,永久代理论上是堆的一部分,和新生代老年代的地址是连续的。
1.8之后用元空间代替永久代。

元空间是直接存在内存中的,并不在java虚拟机中,因此元空间依赖于内存大小。当然也可以自定义元空间大小。

元空间存储类的元信息,而将静态变量和常量池等并入堆中。相当于原来永久代的数据被分到了堆和元空间中。

 

JVM与多线程关系
 

类成员变量,单例多线程情况下,不安全,所有线程处理的同一个变量(不管是对象还是基本数据都不安全,其存在堆内)

类成员方法中的局部变量,单例多线程情况下,基本数据完全安全,存在栈中,每个线程独有。局部对象还是存在堆中所以线程不安全,但是一般在非本线程中不会存在对其不安全的引用(因此可以默认局部对象都是安全的,特殊情况再考虑局部对象)

eg:
void test(){
User user = new User();      
}

引用存在栈中线程独有,是线程安全的。对象在堆,线程不安全

当两个线程同时执行该方法时,第一个线程A  在自己栈中创建 user引用,指向堆内创建User类型的对象1
第二个线程B进来,也在自己栈中创建user引用,并也在堆内创建一个User类型的对象2(存活两个引用两个对象)

两个线程中的user引用是不同的,分别指向两个对象存储区。所以两个线程拿到的对象也是不同的,这样是安全的。
除非你在线程A中引用到了第二个线程B创建的对象2  那么存在不安全的情况(但是基本不存在这种情况)

 

 三种内存溢出解决方法


stackoverflowererror  超过栈深,溢出  

1.查看代码是否有无线递归使栈深溢出
2. -Xss 1M     通过-Xss扩大栈大小

 
 Java.lang.OutOfMemoryError: Java heap space        堆内存溢出(包括新生区和老年区)
首先检查程序有没有限入死循环一直频繁new对象并无法及时GC回收
1.-Xms512m -Xmx1024m     扩容
 

 Java.lang.OutOfMemoryError: PermGen space          永久区溢出(jdk8之后已经移除该区域,替换为Metaspace)
这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,
它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对
PermGen space进行清理,所以如果你的应用jar包中有很多CLASS的话,就很可能出现PermGen space错误

1. -XX:PermSize=512M -XX:MaxPermSize=512m        扩容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值