對於全部的java開發人員來講,瞭解和熟悉JVM的內存結構是很是重要的,不管是對於開發時的一些參數說的設置仍是維護時的異常排查都有很大的幫助,下面咱們先來了解下JVM內存結構java
從JDK1.8開始,JVM內存結構發生一點變化多線程
程序計數器(Program Counter Register)是一塊較小的內存空間,主要能夠看做當前線程所執行的字節碼的行號指示器。它會指示出下一條將要執行指令的地址。
ide
// VM Args: -Xss128k (將虛擬機棧設爲128k大小)
public class Test {
public int length = 0;
public void stackLeak() {
length++;
stackLeak();
}
//運行下本代碼會出先StackOverflowError
public static void main(String[] args) {
Test test = new Test();
try {
test.stackLeak();
} catch(Throwable e) {
System.out.println("stack length:" + test.length);
throw e;
}
}
}
複製代碼
// VM Args:-Xss2M
public class JavaVMStackOOM {
private void dontStop() {
while (true) {
}
}
//運行本代碼會出現OutOfMemoryError異常,可是運行此代碼可能會致使Windows直接掛了,因此得注意,記得保存本身手頭的工做再決定是否是運行
public static void main(String[] args) {
while(true) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
dontStop();
}
});
thread.start();
}
}
}
複製代碼
//VM Args:-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
public class HeapOOM {
static class OOMObject {
}
//運行這段代碼會出現OutOfMemoryError異常
public static void main(String[] args) {
List<OOMObject> list = new ArrayList<>();
while (true) {
list.add(new OOMObject());
}
}
}
複製代碼
//VM args : -XX:PermSize=10M -XX:MaxPermSize=10M
public class JavaMethodAreaOOM {
public static void main(String[] args) {
while (true) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OOMObject.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
return proxy.invokeSuper(obj, args);
}
});
enhancer.create();
}
}
}
複製代碼
//VM args : -XX:PermSize=10m -XX:MaxPermSize=10m
public class RuntimeConstantPoolOOM {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
int i = 0;
while (true) {
list.add(String.valueOf(i++).intern());
}
}
}
複製代碼
本文主要總結了下JVM的內存結構以及每一個結構區相應的存放內容和溢出異常,不少只是借鑑於《深刻理解Java虛擬機++JVM高級特性與最佳實踐這本書》,若是想更好的瞭解的朋友也能夠去看看這本書,寫的很好很詳細!佈局