并发和线程

并行和并发

1.并行跟并发有什么区别?
从操作系统的角度来看,线程是CPU分配的最小单位。

并行就是同一时刻,两个线程都在执行。这就要求有两个CPU去分别执行两个线程。
并发就是同一时刻,只有一个执行,但是一个时间段内,两个线程都执行了。并发的实现依赖于CPU切换线程,因为切换的时间特别短,所以基本对于用户是无感知的。

就好像我们去食堂打饭,并行就是我们在多个窗口排队,几个阿姨同时打菜;并发就是我们挤在一个窗口,阿姨给这个打一勺,又手忙脚乱地给那个打一勺。

进程和线程

进程:进程是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。我所理解的就是,一个服务就是一个进程. 比如:双击QQ,启动QQ,然后QQ把各种资源加载进内存,  这时,一个进程就诞生了.
线程:线程是进程的一个执行路径,一个进程中至少有一个线程,进程中的多个线程共享进程的资源。
操作系统在分配资源时是把资源分配给进程的, 但是 CPU 资源比较特殊,它是被分配到线程的,因为真正要占用CPU运行的是线程,所以也说线程是 CPU分配的基本单位。

比如在Java中,当我们启动 main 函数其实就启动了一个JVM进程,而 main 函数在的线程就是这个进程中的一个线程,也称主线程。

jvm内存

  

下面的图是上面的图的进一步解释

Java内存模型(JMM)

1.堆和栈都是 在Java语言虚拟机 层面上的.

栈内存线程私有的,  是什么意思呢, 可以理解为每个线程都有自己的一个栈内存, 它们之间互不可见互不影响.

堆内存是线程共享的.就是说每个线程都能共享堆内存的资源.

比如,堆内存有个int age= 1,那么a线程先把用到的堆内存的资源拷贝到自己的栈内存,就是 int age =1拷贝到自己的栈内存中,然后再让int age =2,再把int age =2放回线程共享的堆内存中,  当其他线程去读取age的值时就变成了int age =2;

2.Java内存模型(JMM)定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(Main Memory)中,每个线程都有一个私有的本地内存(Local Memory),本地内存中存储了该线程以读/写共享变量的副本。

堆内存 ,数组会把自己的实体对象放到堆内存,   把实体对象的地址存放到栈内存  图

 类的定义 图

 对象内存指向图

 成员变量和局部变量

然后每个方法都有自己的栈帧,栈帧里包括局部变量表,操作数栈,动态链接,方法出口四个部分.

 经过上面的图片知识学习,大致总结下栈内存,堆内存,和方法区都放哪些东西

栈内存

(线程私有)

堆内存

(线程共享)

(包含字符串常量池)

方法区

(线程共享)

(包含运行时常量池)

类new出的实例对象在堆内存的引用地址

放类new出来的实例对象类的信息,运行时常量池.方法数据.方法代码
数组引用地址放数组new出来的实例对象
集合引用地址放数组new出来的实例对象
字符串引用地址

字符串常量池存放字符串对象的引用地址,

字符串对象创建在堆内存内,

变量

局部变量

成员变量
常量(除字符串外)引用地址

用final修饰的变量

基本类型

int a = 3

引用地址3 存在常量池中

上面的表格先等一下,先说一下方法区

 什么是方法区

方法区,是JVM概念上的一个区,并不会随着JDK版本的变化而变化。

但是,方法区的具体实现,却会随着JDK版本的变化而变化的。

JDK7以前,方法区的实现是在“永久代”里;到了JDK8以后,则在Metadata空间里。

 方法区的位置?

《Java虚拟机规范》中明确说明:尽管所有的方法区在逻辑上是属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩。但对于HotSpotJVM而言,方法区还有一个别名叫做Non-Heap(非堆),目的就是要和堆分开。

所以,方法区可以看作是一块独立于Java堆的内存空间.

方法区被线程共享吗?

是的,和堆内存一样,是被线程共享的

方法区都存什么?

java官方书上说:它储存每个类的结构,例如运行时常量池,字段和方法数据,以及方法和构造函数的代码,包括用于类和实例初始化以及接口初始化的特殊方法,

百度说:它用于存储已被虚拟机加载的类信息, 常量, 静态变量, 即时编译器编译后的代码等数据

理解后简化说: 存放类的信息.运行时常量池.方法数据.方法代码.

方法区的理解

  • 方法区(Method Area)与Java堆一样,是各个线程共享的内存区域
  • 多个线程同时加载统一个类时,只能有一个线程能加载该类,其他线程只能等等待该线程加载完毕,然后直接使用该类,即类只能加载一次。
  • 方法区在JVM启动的时候被创建,并且它的实际物理内存空间和Java堆区一样都可以是不连续的。
  • 方法区的大小,跟堆空间一样,可以选择固定大小或者可扩展。
  • 方法区是接口,元空间或者永久代是方法区的实现
  • 方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类,导致方法区溢出,虚拟机同样会抛出内存溢出错误:
  • java.lang.OutofMemoryError:PermGen space(JDK7之前)
  • 或者java.lang.OutOfMemoryError:Metaspace(JDK8之后)
  • 举例说明
  • 1.方法区 OOM加载大量的第三方的jar包
  • 2.Tomcat部署的工程过多(30~50个)
  • 3.大量动态的生成反射类

 关闭JVM就会释放这个区域的内存。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值