五月六日

算法部分:完成单调栈例题部分 496. 739. 503
单调栈模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int[] calculateGreaterElement(int[] nums) {
int n = nums.length;
// 存放答案的数组
int[] res = new int[n];
Stack<Integer> s = new Stack<>();
// 倒着往栈里放
for (int i = n - 1; i >= 0; i--) {
// 判定个子高矮
while (!s.isEmpty() && s.peek() <= nums[i]) {
// 矮个起开,反正也被挡着了。。。
s.pop();
}
// nums[i] 身后的更大元素
res[i] = s.isEmpty() ? -1 : s.peek();
s.push(nums[i]);
}
return res;
}

关于栈的习题:71. 143. 20. 155.

JVM主要结构:执行引擎,运行时数据区、类加载器
内存区主要划分:堆、虚拟机栈、本地方法栈、方法区、PC
对象创建过程:new一个对象时,先在本地变量池中查找类的符号引用,检查类是否已经加载、解析、初始化,如果没有会先进行类加载;已经加载JVM会为对象分配内存并初始化(初始值、对象头、init())
对象销毁:对象不被引用后变成垃圾。通过可达性算法分析是否回收对象
java -XX:+PrintGCDetails -version
查看GC回收器
堆内存的分配策略:指针碰撞和空闲列表。
指针碰撞适用于管理简单、碎片化较少的内存区域,如年轻代;而空闲列表适用于内存碎片化较严重或对象大小差异较大的场景如老年代。
指针碰撞:分配内存时,JVM维护一个指针,指向下一个可用地址,每次分配时指针后移即可。
空闲列表:JVM维护一个列表,记录堆中为占用的内存块,申请内存时,遍历列表。
内存分配竞争问题:当两个线程分别为新对象分配内存时,可能出现内存竞争问题,为了解决该问题,JVM为每个线程保留了一小部分空闲空间TLAB也就是线程本地分配缓冲区,用于存放该线程分配的对象。线程需要分配对象时,优先从TLAB中分配
对象的内存布局:对象头、实例数据、对齐填充
对象头主要包括mark word、类型指针、数组记录数据。mark word存储对象运行时的状态信息:GC标记、锁、哈希值等(64位OS占8字节、32位OS占4字节);类型指针指向Class对象,用于支持多态和方法调用;如果对象是数组类型,还会有一个额外的数组长度字段。占 4 个字节。指针压缩开启后,类型指针占4字节。(JDK8中默认开启)
new Object()对象内存大小:8+4+4=16


五月六日
http://bloomivy.github.io/2025/05/06/五月六日/
作者
Bloom
发布于
2025年5月6日
许可协议