[GC (System.gc()) [PSYoungGen: 15492K->10728K(76288K)] 15492K->11000K(251392K), 0.0066473 secs] [Times: user=0.08 sys=0.02, real=0.01 secs]
[Full GC (System.gc()) [PSYoungGen: 10728K->0K(76288K)] [ParOldGen: 272K->10911K(175104K)] 11000K->10911K(251392K), [Metaspace: 3492K->3492K(1056768K)], 0.0097940 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
Heap
PSYoungGen total 76288K, used 655K [0x00000000fab00000, 0x0000000100000000, 0x0000000100000000)
eden space 65536K, 1% used [0x00000000fab00000,0x00000000faba3ee8,0x00000000feb00000)
from space 10752K, 0% used [0x00000000feb00000,0x00000000feb00000,0x00000000ff580000)
to space 10752K, 0% used [0x00000000ff580000,0x00000000ff580000,0x0000000100000000)
ParOldGen total 175104K, used 10911K [0x00000000f0000000, 0x00000000fab00000, 0x00000000fab00000)
object space 175104K, 6% used [0x00000000f0000000,0x00000000f0aa7d08,0x00000000fab00000)
Metaspace used 3498K, capacity 4498K, committed 4864K, reserved 1056768K
class space used 387K, capacity 390K, committed 512K, reserved 1048576K
2、调用 localvarGC2() 方法
由于 buffer 数组对象没有引用指向它,执行 System.gc() 将被回收
JAVA
[GC (System.gc()) [PSYoungGen: 15492K->808K(76288K)] 15492K->816K(251392K), 0.0294475 secs] [Times: user=0.00 sys=0.00, real=0.04 secs]
[Full GC (System.gc()) [PSYoungGen: 808K->0K(76288K)] [ParOldGen: 8K->640K(175104K)] 816K->640K(251392K), [Metaspace: 3385K->3385K(1056768K)], 0.0054210 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
Heap
PSYoungGen total 76288K, used 1966K [0x00000000fab00000, 0x0000000100000000, 0x0000000100000000)
eden space 65536K, 3% used [0x00000000fab00000,0x00000000faceb9e0,0x00000000feb00000)
from space 10752K, 0% used [0x00000000feb00000,0x00000000feb00000,0x00000000ff580000)
to space 10752K, 0% used [0x00000000ff580000,0x00000000ff580000,0x0000000100000000)
ParOldGen total 175104K, used 640K [0x00000000f0000000, 0x00000000fab00000, 0x00000000fab00000)
object space 175104K, 0% used [0x00000000f0000000,0x00000000f00a01a8,0x00000000fab00000)
Metaspace used 3392K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 379K, capacity 388K, committed 512K, reserved 1048576K
3、调用 localvarGC3() 方法
虽然出了代码块的作用域,但是 buffer 数组对象并没有被回收
JAVA
[GC (System.gc()) [PSYoungGen: 15492K->840K(76288K)] 15492K->11088K(251392K), 0.0070281 secs] [Times: user=0.08 sys=0.00, real=0.01 secs]
[Full GC (System.gc()) [PSYoungGen: 840K->0K(76288K)] [ParOldGen: 10248K->10900K(175104K)] 11088K->10900K(251392K), [Metaspace: 3386K->3386K(1056768K)], 0.0084464 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
Heap
PSYoungGen total 76288K, used 1966K [0x00000000fab00000, 0x0000000100000000, 0x0000000100000000)
eden space 65536K, 3% used [0x00000000fab00000,0x00000000faceb9e0,0x00000000feb00000)
from space 10752K, 0% used [0x00000000feb00000,0x00000000feb00000,0x00000000ff580000)
to space 10752K, 0% used [0x00000000ff580000,0x00000000ff580000,0x0000000100000000)
ParOldGen total 175104K, used 10900K [0x00000000f0000000, 0x00000000fab00000, 0x00000000fab00000)
object space 175104K, 6% used [0x00000000f0000000,0x00000000f0aa52e8,0x00000000fab00000)
Metaspace used 3393K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 379K, capacity 388K, committed 512K, reserved 1048576K
[GC (System.gc()) [PSYoungGen: 15492K->776K(76288K)] 15492K->784K(251392K), 0.0009430 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (System.gc()) [PSYoungGen: 776K->0K(76288K)] [ParOldGen: 8K->646K(175104K)] 784K->646K(251392K), [Metaspace: 3485K->3485K(1056768K)], 0.0065829 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
Heap
PSYoungGen total 76288K, used 1966K [0x00000000fab00000, 0x0000000100000000, 0x0000000100000000)
eden space 65536K, 3% used [0x00000000fab00000,0x00000000faceb9f8,0x00000000feb00000)
from space 10752K, 0% used [0x00000000feb00000,0x00000000feb00000,0x00000000ff580000)
to space 10752K, 0% used [0x00000000ff580000,0x00000000ff580000,0x0000000100000000)
ParOldGen total 175104K, used 646K [0x00000000f0000000, 0x00000000fab00000, 0x00000000fab00000)
object space 175104K, 0% used [0x00000000f0000000,0x00000000f00a1b88,0x00000000fab00000)
Metaspace used 3498K, capacity 4498K, committed 4864K, reserved 1056768K
class space used 387K, capacity 390K, committed 512K, reserved 1048576K
public class StopTheWorldDemo {
public static class WorkThread extends Thread {
List<byte[]> list = new ArrayList<byte[]>();
public void run() {
try {
while (true) {
for(int i = 0;i < 1000;i++){
byte[] buffer = new byte[1024];
list.add(buffer);
}
if(list.size() > 10000){
list.clear();
System.gc();//会触发full gc,进而会出现STW事件
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public static class PrintThread extends Thread {
public final long startTime = System.currentTimeMillis();
public void run() {
try {
while (true) {
// 每秒打印时间信息
long t = System.currentTimeMillis() - startTime;
System.out.println(t / 1000 + "." + t % 1000);
Thread.sleep(1000);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public static void main(String[] args) {
WorkThread w = new WorkThread();
PrintThread p = new PrintThread();
w.start();
p.start();
}
}
关闭工作线程 w ,观察输出:当前时间间隔与上次时间间隔基本是每隔1秒打印一次
JAVA
0.1
1.1
2.2
3.2
4.3
5.3
6.3
7.3
Process finished with exit code -1
开启工作线程 w ,观察打印输出:当前时间间隔与上次时间间隔相差 1.3s ,可以明显感受到 Stop the World 的存在
JAVA
0.1
1.4
2.7
3.8
4.12
5.13
Process finished with exit code -1
Object obj = new Object();// 声明强引用
SoftReference<Object> sf = new SoftReference<>(obj);
obj = null; //销毁强引用
软引用代码举例
代码
JAVA
public class SoftReferenceTest {
public static class User {
public User(int id, String name) {
this.id = id;
this.name = name;
}
public int id;
public String name;
@Override
public String toString() {
return "[id=" + id + ", name=" + name + "] ";
}
}
public static void main(String[] args) {
//创建对象,建立软引用
// SoftReference<User> userSoftRef = new SoftReference<User>(new User(1, "songhk"));
//上面的一行代码,等价于如下的三行代码
User u1 = new User(1,"songhk");
SoftReference<User> userSoftRef = new SoftReference<User>(u1);
u1 = null;//取消强引用
//从软引用中重新获得强引用对象
System.out.println(userSoftRef.get());
System.out.println("---目前内存还不紧张---");
System.gc();
System.out.println("After GC:");
// //垃圾回收之后获得软引用中的对象
System.out.println(userSoftRef.get());//由于堆空间内存足够,所有不会回收软引用的可达对象。
System.out.println("---下面开始内存紧张了---");
try {
//让系统认为内存资源紧张、不够
// byte[] b = new byte[1024 * 1024 * 7];
byte[] b = new byte[1024 * 7168 - 635 * 1024];
} catch (Throwable e) {
e.printStackTrace();
} finally {
//再次从软引用中获取数据
System.out.println(userSoftRef.get());//在报OOM之前,垃圾回收器会回收软引用的可达对象。
}
}
}
JVM参数
-Xms10m -Xmx10m
在 JVM 内存不足时,会清理软引用对象
输出结果:
JAVA
[id=1, name=songhk]
---目前内存还不紧张---
After GC:
[id=1, name=songhk]
---下面开始内存紧张了---
null
java.lang.OutOfMemoryError: Java heap space
at com.atguigu.java1.SoftReferenceTest.main(SoftReferenceTest.java:48)
Process finished with exit code 0