面向相关 - JVM相关

【什么是进程、线程?】
os中,进程只负责向操作系统申请资源,包括CPU、内存,线程是包含在进程里面的,可以共用这些资源。
在Java中,我们启动一个main函数就启动了一个JVM进程。main所在的线程我们称之为主线程,其他的线程共用这个进程中的【堆、方法区】资源,但线程之间还是具有自己的【栈、程序计数器】,这样操作系统在切换线程代价就比较小。

  • 为何私有?
    PC是方便线程切换,切回来还能继续执行;栈是为了保存局部变量,不被其他线程访问

然后就有了,堆 和 方法区
方法区:加载的类信息、常量、静态变量
堆:存放新创建的对象实例
由此展开了【类加载】、【垃圾回收】

回到【JVM】话题。。。

【对象的创建过程】
1、类加载检查
2、分配内存。分配方法针对规整堆:“指针移动”、不规则堆:“空闲列表”
3、初始化零值(Java针对一些常用的数据类型有其默认的零值)
4、设置对象头,对象本身数据(哈希码、GC分代年龄、锁状态)、指向类元数据
5、执行init方法,按照程序指定赋值。

【垃圾回收】
为了方便回收内存,所以将堆分为三大块:1、新生代 2、年老代 3、永久代


全面理解Java内存模型
1、线程通信 -- 内存共享、消息传递
2、Java内存模型:主存是共享、工作内存是独享的,线程操作都是工作内存的副本,而不直接操作主存。于是就有了共享变量的可见性问题
3、内存模型实现:
调用栈和本地变量都存储在栈区,对象都存储在堆区

大体上看,就分为【线程栈】、【堆】
4、内存屏障(Memory Barrier)有两个功能,1、不管什么指令都不能和这条Memory Barrier指令重排序;2、强制刷出各种CPU cache到主存

线程通信
1、共享对象方式实现通信,线程必须持有同一对象的引用,通过修改boolean值,完成线程通信,但这样存在一方忙等

2、每个对象本身都可以被作为锁,Object对象中的方法有:wait()、notify(),wait() 可以解决忙等。
3、线程必须在同步块中调用wait()、notify()方法(必须是同一对象)
于是

synchronized (mySignal){
  mySignal.wait();
  System.out.println("线程B计算结果为:"+threadD.count);
}

--
synchronized (mySignal){
  mySignal.notify();//计算完成调用对象的notify()方法,唤醒因调用这个对象wait()方法而挂起的线程
}

4、wait()可以放弃CPU占用、同时释放掉监控对象锁
另外线程被唤醒时,还是要申请监控对象锁。

posted @ 2022-07-17 14:35  spongie  阅读(21)  评论(0编辑  收藏  举报