java基础_JVM
2021-11-05 17:01:14 0 举报
AI智能生成
JAVA基础
作者其他创作
大纲/内容
java代码执行过程
生成Class文件
装载Class
加载
生成Class对象<br>
验证
确保Class符合jvm要求
准备
在方法区中分配这些变量所使<br>用的内存空间<br>
解析
指虚拟机将常量池中的符号引用替换为直接引用的过程
初始化
执行类构造器<client>方法的过程<br>
执行Class<br>
解释执行
编译执行
client
server
类加载器
启动类加载器(Bootstrap ClassLoader)
java_home\lib<br>
扩展类加载器(Extension ClassLoader)<br>
java_home\jre\lib<br>
应用程序类加载器(Application ClassLoader)
classpath
自定义类加载器<br>
用户指定<br>
内存管理<br>
内存空间
堆,线程共享
young<br>
eden
survivor from<br>
survivor to
old
程序计数器,线程共享
方法区,线程共享<br>8改为元空间,放在物理内存中
Class<br>
meta数据
栈->栈帧,线程私有<br>
局部变量表<br>
操作数栈<br>
动态链接
方法出口<br>
本地方法栈,线程私有
内存分配
堆分配
栈分配
TLAB线程本地分配缓存区
条件:对象的作用域不会逃逸出方法之外,方法结束快速释放<br>
默认Eden空间的1%
-XX:UseTLAB
连续空间撞针分配<br>
假设Java堆中内存是绝对规整的,所有用过的内存都放在一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间那边挪动一段与对象大小相等的距离,这种分配方式称为“指针碰撞”(Bump the Pointer)
会导致内存碎片
内存回收
对象存活判断
引用计数
引用计数属性,为0回收
无法解决对象相互循环引用
可达性分析
GcRoots<br>
虚拟机栈中引用的对象
方法区中类静态属性实体引用的对象
方法区中常量引用的对象
本地方法栈中JNI引用的对象
任何引用链相连,可以回收
垃圾收集算法
标记 -清除算法
复制算法
标记-压缩算法
分代收集算法
分区收集算法
垃圾回收器
Serial
单线程复制算法
ParNew
Serial+多线程
Parallel Scavenge
多线程复制算法、吞吐量大
Serial Old
单线程标记整理算法<br>
Parallel Old
多线程标记整理算法<br>
CMS
多线程标记清除算法、停顿少
初始标记
并发标记<br>
重新标记<br>
并发清除<br>
G1
基于标记-整理算法,不产生碎片、停顿少<br>
假设Java堆中内存是绝对规整的,所有用过的内存都放在一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间那边挪动一段与对象大小相等的距离,这种分配方式称为“指针碰撞”(Bump the Pointer)
内存状况分析
jstat
S0C:第一个幸存区的大小<br>S1C:第二个幸存区的大小<br>S0U:第一个幸存区的使用大小<br>S1U:第二个幸存区的使用大小<br>EC:伊甸园区的大小<br>EU:伊甸园区的使用大小<br>OC:老年代大小<br>OU:老年代使用大小<br>MC:方法区大小<br>MU:方法区使用大小<br>CCSC:压缩类空间大小<br>CCSU:压缩类空间使用大小<br>YGC:年轻代垃圾回收次数<br>YGCT:年轻代垃圾回收消耗时间<br>FGC:老年代垃圾回收次数<br>FGCT:老年代垃圾回收消耗时间<br>GCT:垃圾回收消耗总时间
jmap
heap: 显示Java堆详细信息<br>
histo[:live]: 显示堆中对象的统计信息
dump:<dump-options>:生成堆转储快照 <br>jmap -dump:format=b,file=heapdump.phrof pid<br>
visualvm<br>
jconsole<br>
Athas阿里<br>
mat
多线程
基本概念<br>
线程概念
线程实现<br>
继承Tread
实现Runnable接口
使用线程池
常用方法<br>
yield<br>
让出时间片
sleep
等待固定时间
会有中断异常
join<br>
当前线程加塞等待另一个线程<br>
stop
弃用,会释放所有monitor
interrupt
isInterrupted()判断执行XX
interrupt()打招呼
suspend挂起,不会释放临界资源,不推荐使用
resume恢复执行,不推荐使用<br>
wait
先拿到对象的监视器<br>
释放线程的监视器
notify
先拿到对象的监视器
随机唤醒一个
setDaemon
线程启动前设置
synchronized
进入同步代码前要获得给定对象的锁
线程状态<br>
new
Runnable<br>
Ready
Running
Terminated<br>
Blocked<br>
Waiting<br>
TimedWaiting<br>
线程容易发生的问题
死锁deadlock
多个线程间相互获取对方的资源导致互相等待
饥饿starvation
线程无法获得到需要的资源,导致无法执行
活锁liveLock
动态获取相同一种资源而等待
并发级别
阻塞
无障碍
最弱障碍,自由出入临界区,有竞争回滚数据。最终可能都失败。
无锁
无障碍,保证有一个线程胜出,例CAS
无等待
无锁,所有线程都必须有限步完成。无饥饿。例:读,写副本
定律
amdahl阿姆达尔定律
定义了串行系统并行化后的加速比的计算公式和理论上限
gustafson古斯塔夫定律
处理器的个数,串行比和加速比之间的关系。
线程同步<br>
异常与锁<br>
volatile
wait notify线程通信
JUC同步工具
executor
locks
ReentrantLock<br>
可重入<br>
但要重复退出
可中断<br>
lockInterruptibly
可限时
超时不能获得锁,就返回false,不会永久等待构成死锁<br>
tryLock(),<br>
公平锁<br>
ReentrantLock(boolean fair)
Condition
类似于 Object.wait()和bject.notify()<br>与ReentrantLock结合使用
await
signal
signalAll<br>
Semaphore<br>
共享锁,运行多个线程同时临界区
acquire
tryAcquire
release<br>
ReadWriteLock
是JDK5中提供的读写分离锁
读-读不互斥,读-写互斥,写-写互斥<br>
ReentrantReadWriteLock:readLock(),writeLock()<br>
CountDownLatch
倒数计时器
new CountDownLatch(10)
countDown
await<br>
CyclicBarrier<br>
循环栅栏
CyclicBarrier(int parties, Runnable barrierAction)
await<br>
LockSupport
提供线程阻塞原语
park()
unpark(t)<br>
collections<br>
Queue<br>
ConcurrentLinkedQueue<br>
BlockingQueue<br>
ArrayBlockingQueue<br>
DelayQueue<br>
LinkedBlockingQueue<br>
PriorityBlockingQueue<br>
SynchronousQueue
Deque
ArrayDeque<br>
IdentityLinkedList<br>
LinkedList
BlockingDeque<br>
LinkedBlockingDeque<br>
CopyOnWriteArrayList<br>
CopyOnWriteArraySet
ConcurrentSkipListSet
ConcurrentMap
ConcurrentHashMap
ConcurrentNavigableMap<br>
ConcurrentSkipListMap
tools
AtomicXXX原子类<br>
CAS(一个指令cmpxchg)
Unsafe<br>
AtomicInteger
getAndSet
compareAndSet
getAndIncrement
getAndAdd
AtomicReference
对引用进行修改
AtomicStampedReference<br>
ABA,如:充值,时间戳因子
AtomicIntegerArray
支持无锁的数组
AtomicIntegerFieldUpdater
让普通变量也享受原子操作
同步容器
AbstractQueuedSynchronizer
ReentrantLock/Semaphore/CountDownLatch
线程池
Disruptor
对象在内存中的结构
对象头<br>
MarkWord 4个字节
哈希码、分代年龄、锁标志位、<br>偏向线程ID、偏向时间戳等信息<br>
类型指针 4个字节
标识是哪个类的实例<br>
实例数据
有效信息
存储顺序
分配策略参数<br>
相同宽度的字段总是被分配到一起
源码中定义顺序
对齐填充
不是必然存在
满足8字节的整数倍
引用类型
强引用<br>
处于可达状态,不被回收<br>
软引用
内存不足够时回收<br>
弱引用<br>
下一次垃圾回收<br>
虚引用
不存储<br>跟踪对象被垃圾回收的状态<br>
IO
IO 模型
阻塞 IO 模型
交出CPU
非阻塞 IO 模型
不会交出 CPU<br>用户线程不断地询问内核数据是否就绪<br>
多路复用 IO 模型<br>
有一个线程不断去轮询多个 socket 的状态,<br>当 socket 真正有读写事件时,才真正调用实际的 IO 读写操作。<br>
信号驱动 IO 模型<br>
IO请求注册信号函数,收到信号后调用 IO 读写<br>
异步 IO 模型
内核完成后通知用户线程使用数据<br>
io包
字节流
Inputstream
FileInputstream
ByteArrayInputstream
ObjectInputstream
PipedInputstream
SequenceInputstream<br>
StringBufferInputstream
Outputstream
字符流<br>
reder
buffered<br>
stirng
charArray
filter<br>
inputstream<br>
fileReader
piped<br>
writer
NIO
核心
Channel(通道、双向)<br>
Buffer(缓冲区)<br>
Selector监听多个通道的事件
包
channel包
Channels
FileChannel<br>
Pipe<br>
Selector
ServerSocketChannel等<br>
SocketChannel
charSet包<br>
CharSet
CharSetDecoder<br>
CharSetEncoder等<br>
Buffer
ByteBuffer<br>
CharBuffer<br>
IntBuffer
DoubleBuffer等
ByteOrder
mappedByteBuffer<br>
JMM
原子性
一旦开始不会被干扰
有序性
在并发时可能会出现乱序
java 代码要转成汇编代码
汇编代码执行步骤:取指,译码和取寄存器操作数,执行或者有效地址计算,存储器访问,写回<br>
指令重排可以使流水线更加顺畅
可见性
当一个线程修改了某一个共享变量的值,其他线程是否能够立即知道这个修改
产生原因:编译器优化,硬件优化
Happen-Before
程序顺序原则
volatile规则:volatile变量的写,先发生于读<br>
锁规则:解锁(unlock)必然发生在随后的加锁(lock)前<br>
传递性:A先于B,B先于C,那么A必然先于C<br>
线程的start()方法先于它的每一个动作<br>
线程的所有操作先于线程的终结
线程的中断(interrupt())先于被中断线程的代码<br>
对象的构造函数执行结束先于finalize()方法<br>
线程安全的概念<br>
java常用命令
jps
显示当前所有java进程pid的命令
jstack
堆栈跟踪工具
0 条评论
下一页