玩點(diǎn)深入的:Java 虛擬機(jī)內(nèi)存結(jié)構(gòu)及編碼實(shí)戰(zhàn)
本文來源:不會coding
了解JVM內(nèi)存結(jié)構(gòu)的目的
JVM內(nèi)存結(jié)構(gòu)簡介
-
程序計(jì)數(shù)器:當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器。 -
虛擬機(jī)棧:Java方法執(zhí)行的內(nèi)存模型,用于存儲局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口等信息。 -
本地方法棧:本地方法執(zhí)行的內(nèi)存模型,和虛擬機(jī)棧非常相似,其區(qū)別是本地方法棧為JVM使用到的Native方法服務(wù)。 -
堆:用于存儲對象實(shí)例,是垃圾收集器管理的主要區(qū)域。 -
方法區(qū):用于存儲已被JVM加載的類信息、常量、靜態(tài)變量、即時編譯器編譯后的代碼等數(shù)據(jù)。
程序計(jì)數(shù)器
虛擬機(jī)棧
/**
* VM Args: -Xss128k
*/
public class JVMStackSOF {
private int stackLength = 1;
public void stackLeak() {
stackLength++;
stackLeak();
}
public static void main(String[] args) {
JVMStackSOF sof = new JVMStackSOF();
try {
sof.stackLeak();
} catch (Throwable e) {
System.out.println("Stack length:" + sof.stackLength);
throw e;
}
}
}
在運(yùn)行之前,設(shè)置JVM的參數(shù)為-Xss128k,運(yùn)行結(jié)果如下:
Stack length:1002
Exception in thread "main" java.lang.StackOverflowError
at OneMoreStudy.JVMStackSOF.stackLeak(JVMStackSOF.java:10)
at OneMoreStudy.JVMStackSOF.stackLeak(JVMStackSOF.java:11)
at OneMoreStudy.JVMStackSOF.stackLeak(JVMStackSOF.java:11)
......
/**
* VM Args: -Xss2M
*/
public class JVMStackOOM {
private void dontStop() {
while (true) {
}
}
public void stackLeakByThread() {
while (true) {
Thread t = new Thread(new Runnable() {
public void run() {
dontStop();
}
});
t.start();
}
}
public static void main(String[] args) {
JVMStackOOM oom = new JVMStackOOM();
oom.stackLeakByThread();
}
}
Exception in thread "main" java.lang.OutMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Unknown Source)
at OneMoreStudy.JVMStackOOM.stackLeakByThread(JVMStackOOM.java:18)
at OneMoreStudy.JVMStackOOM.main(JVMStackOOM.java:24)
本地方法棧
堆
/*
* VM Args: -Xms20M -Xmx20M
*/
public class HeapOOM {
static class OOMObject{
}
public static void main(String[] args){
List<OOMObject> list = new ArrayList<OOMObject>();
while(true){
//把對象實(shí)例放入列表中,
//使其一直被引用,不會被垃圾回收
list.add(new OOMObject());
}
}
}
在運(yùn)行之前,設(shè)置JVM的參數(shù)為-Xms20M -Xmx20M,運(yùn)行結(jié)果如下:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.util.Arrays.copyOf(Unknown Source)
at java.util.ArrayList.grow(Unknown Source)
at java.util.ArrayList.ensureExplicitCapacity(Unknown Source)
at java.util.ArrayList.ensureCapacityInternal(Unknown Source)
at java.util.ArrayList.add(Unknown Source)
at OneMoreStudy.HeapOOM.main(HeapOOM.java:18)
方法區(qū)
/*
* VM Args: -XX:PermSize=2M -XX:MaxPermSize=2M
*/
public class RuntimeConstantPoolOOM {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
for (int i = 0; i < 100000; i++) {
System.out.println(i);
//將i轉(zhuǎn)化為字符串,
//并且調(diào)用intern(),把字符串放在運(yùn)行時常量池
list.add(String.valueOf(i).intern());
}
}
}
......
35813
35814
Exception in thread "main" java.lang.OutOfMemoryError: PermGen space
at java.lang.String.intern(Native Method)
at OneMoreStudy.RuntimeConstantPoolOOM.main(RuntimeConstantPoolOOM.java:12)
......
99996
99997
99998
99999
/*
* VM Args: -XX:PermSize=2M -XX:MaxPermSize=2M
*/
public class MethodAreaOOM {
static class OOMObject {
}
public static void main(String[] args) {
for (int i = 0; i < 300; i++) {
System.out.println(i);
createNewClass();
}
}
private static void createNewClass() {
//這里使用了CGLIB,動態(tài)創(chuàng)建類,載入方法區(qū)
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OOMObject.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method,
Object[] args, MethodProxy proxy) throws Throwable {
return proxy.invokeSuper(obj, args);
}
});
enhancer.create();
}
}
......
Caused by: java.lang.OutOfMemoryError: PermGen space
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
... 12 more
Exception in thread "main"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"
......
298
299
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=2M; support was removed in 8.0
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=2M; support was removed in 8.0
總結(jié)
特別推薦一個分享架構(gòu)+算法的優(yōu)質(zhì)內(nèi)容,還沒關(guān)注的小伙伴,可以長按關(guān)注一下:
長按訂閱更多精彩▼
如有收獲,點(diǎn)個在看,誠摯感謝
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點(diǎn),不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!