- 强引用、软引用、弱引用、虚引用分别是什么?
强引用(默认支持模式):当内存不足时,JVM开始垃圾回收,对于强引用的对象,就算是出现了OOM也不会对该对象进行回收,死都不收。软引用:当系统内存充足时对象不会被回收;当系统内存不足时对象会被回收。(应用场景:读取大量本地图片。如果每次读取图片都从硬盘读取则会严重影响性能;如果一次性全部加载到内存中又可能造成内存溢出)弱引用:只要发生gc,就会被回收。虚引用:任何时候都可能被垃圾回收器回收。 知道弱引用的话,能谈谈WeakHashMap吗?
WeakHashMap,它可以实现自清理。就是让map中不用的key数据自动清理掉,用的还留着。
public class WeakHashMapDemo {
public static void main(String[] args) {
myHashMap();
System.out.println("==================");
myWeakHashMap();
}
private static void myWeakHashMap() {
Map map = new WeakHashMap<>();
Integer key = new Integer(2);
String value = "WeakHashMap";
map.put(key, value);
System.out.println(map);
key = null;
System.out.println(map);
System.gc();
System.out.println(map + "t" + map.size());
}
private static void myHashMap() {
Map map = new HashMap<>();
Integer key = new Integer(1);
String value = "HashMap";
map.put(key, value);
System.out.println(map);
key = null;
System.out.println(map);
System.gc();
System.out.println(map + "t" + map.size());
}
}
运行结果:ReferenceQueue:引用队列?
引用队列,在检测到适当的可到达性更改后,垃圾回收器将已注册的引用对象添加到该队列中,实现了一个队列的入队(enqueue)和出队(poll还有remove)操作,内部元素是泛型的Reference,并且Queue的实现,是由Reference自身的链表结构(单向循环链表)所实现的。(在引用中做后置通知)OOM?
StackOverflowError: 栈溢出。应用程序因为深递归导致栈被耗尽了。每当java程序启动一个新线程时,java虚拟机会为他分配一个栈,java栈以帧为单位保持线程运行状态;当线程调用一个方法时,jvm压入一个新的栈帧到这个线程的栈中,只要这个方法还没返回,这个栈帧就存在。如果方法的嵌套调用层次太多(如递归调用),随着java栈中的帧的增多,最终导致这个线程的栈中的所有栈帧的大小的总和大于-Xss设置的值,从而产生StackOverflowError溢出异常。
public class StackOverflowErrorDemo {
public static void main(String[] args) {
stackOverflowError();
}
private static void stackOverflowError() {
stackOverflowError();
}
}
- OutOfMemoryError:Java Heap Space。堆溢出
public class JavaHeapSpaceDemo {
public static void main(String[] args) {
byte[] bytes = new byte[80 * 1024 * 1024];
}
}
- OutOfMemoryError:GC overhead limit exceeded。JVM花费了98%的时间进行垃圾回收,而只得到2%可用的内存,频繁的进行内存回收(最起码已经进行了5次连续的垃圾回收),JVM就会曝出java.lang.OutOfMemoryError: GC overhead limit exceeded错误。OutOfMemoryError:Direct buffer memory。直接内存溢出。OutOfMemoryError:unable to create new native thread。原因:①系统内存耗尽,无法为新线程分配内存;②创建线程数超过了操作系统的限制。解决方案:①排查应用是否创建了过多的线程;②调整操作系统线程数阈值;③增加机器内存;④减小堆内存;⑤减少进程数;⑥减小线程栈大小。OutOfMemoryError:metaspace。元空间溢出。
给定一个正整数 n,生成一个包含 1 到 n 2 n^2 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
模拟顺时针画矩阵的过程:
- 填充上行从左到右
- 填充右列从上到下
- 填充下行从右到左
- 填充左列从下到上
这里一圈下来,我们要画每四条边,这四条边怎么画,每画一条边都要坚持一致的左闭右开,或者左开又闭的原则,这样这一圈才能按照统一的规则画下来。
public int[][] generateMatrix(int n) {
int[][] res = new int[n][n];
// 循环次数
int loop = n / 2;
// 中间位置
int mid = n / 2;
// 定义偏移量
int offset = 1;
// 定义每次循环初始位置
int startX = 0;
int startY = 0;
// 填充数字
int count = 1;
while (loop > 0) {
int i = startX;
int j = startY;
// 上侧填充
for (; j < startY + n - offset; j++) {
res[startX][j] = count++;
}
// 右侧填充
for (; i < startX + n - offset; i++) {
res[i][j] = count++;
}
// 下侧填充
for (; j > startY; j--) {
res[i][j] = count++;
}
// 左侧填充
for (; i > startX; i--) {
res[i][j] = count++;
}
loop--;
startX += 1;
startY += 1;
offset += 2;
}
if (n % 2 == 1) {
res[mid][mid] = count;
}
return res;
}



