关于jvm内存模型以及jvm内存结构划分

好久没有更新博客了 甚是怀念

网上看了很多资料都是对于两者概念比较模糊

首先关于JVM启动流程

在这里插入图片描述
*

接下来是JVM内存结构,是结构并不是内存模型

在这里插入图片描述

PC寄存器

每个线程拥有一个PC寄存器
在线程创建时 创建H
指向下一条指令的地址
执行本地方法时,PC的值为undefined

方法区

保存装载的类信息
	类型的常量池
	字段,方法信息
	方法字节码
通常和永久区(Perm)关联在一起

但是基于JDK改动:
JDK6时,String等常量信息置于方法
JDK7时,已经移动到了堆

Java堆

和程序开发密切相关
应用系统对象都保存在Java堆中
所有线程共享Java堆
对分代GC来说,堆也是分代的

Java栈

线程私有
栈由一系列帧组成(因此Java栈也叫做帧栈)
帧保存一个方法的局部变量、操作数栈、常量池指针
每一次方法调用创建一个帧,并压栈

**

栈、堆、方法区交互

**
在这里插入图片描述
具体代码体现:

public   class  AppMain     
 //运行时, jvm 把appmain的信息都放入方法区 
 { public   static   void  main(String[] args)  
//main 方法本身放入方法区。 
{ Sample test1 = new  Sample( " 测试1 " );  
 //test1是引用,所以放到栈区里, Sample是自定义对象应该放到堆里面 
 Sample test2 = new  Sample( " 测试2 " ); 
 test1.printName(); test2.printName(); } 
public   class  Sample       
 //运行时, jvm 把appmain的信息都放入方法区 
 { private  name;     
 //new Sample实例后, name 引用放入栈区里,  name 对象放入堆里 
 public  Sample(String name) 
 {this .name = name; } //print方法本身放入 方法区里。public   void  printName()    
 { System.out.println(name); } }

接下来才是jvm内存模型
在这里插入图片描述

接下来是关于线程工作内存以及主内存之间数据交互

当数据从主内存复制到工作存储时,必须出现两个动作:第一,由主内存执行的读(read)操作;第二,由工作内存执行的相应的load操作;当数据从工作内存拷贝到主内存时,也出现两个操作:第一个,由工作内存执行的存储(store)操作;第二,由主内存执行的相应的写(write)操作

每一个操作要保证可见性 原子性 有序性
何为原子性:
一旦操作开始,就不会被其他线程所干扰
何为可见性:
当线程A修改共享变量值,线程B能够立刻知道当前修改的共享变量值
何为有序性
是指在单线程环境下,都是按照程序有序的执行,可能有人会问,多线程咋办,所以,这就是接下来的如何保证线程有序性以及线程安全性,这个知识点百度可以解决

涉及到栈 堆 方法区 那么就要涉及到一个OOM(out of Memroy)

堆溢出:集合类中对对象的引用,没有及时处理,导致JVM无法及时回收
**栈溢出:**在需要创建线程的时候,需要为线程分配栈空间,但是栈空间是像操作系统请求的,如果当前操作系统无法满足当前栈空间请求,此刻就会导致内存溢出
***永久区溢出:***永久区溢出现象就是过多对象实体,设置允许回收class
**直接内存溢出:**栈内存,堆内存所占空间过大,导致直接内存不足

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值