精品丰满熟女一区二区三区_五月天亚洲欧美综合网_亚洲青青青在线观看_国产一区二区精选

  • <menu id="29e66"></menu>

    <bdo id="29e66"><mark id="29e66"><legend id="29e66"></legend></mark></bdo>

  • <pre id="29e66"><tt id="29e66"><rt id="29e66"></rt></tt></pre>

      <label id="29e66"></label><address id="29e66"><mark id="29e66"><strike id="29e66"></strike></mark></address>
      學(xué)習(xí)啦>學(xué)習(xí)電腦>電腦硬件知識(shí)>內(nèi)存知識(shí)>

      java內(nèi)存溢出如何產(chǎn)生

      時(shí)間: 捷鋒774 分享

        Java是由Sun Microsystems公司推出的Java面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言(以下簡(jiǎn)稱Java語(yǔ)言)和Java平臺(tái)的總稱。下面是學(xué)習(xí)啦小編帶來(lái)的關(guān)于java內(nèi)存溢出如何產(chǎn)生的內(nèi)容,歡迎閱讀!

        java內(nèi)存溢出如何產(chǎn)生:

        java虛擬機(jī)規(guī)范規(guī)定的java虛擬機(jī)內(nèi)存其實(shí)就是java虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū),其架構(gòu)如下:

        其中方法區(qū)和堆是由所有線程共享的數(shù)據(jù)區(qū)。

        Java虛擬機(jī)棧,本地方法棧和程序計(jì)數(shù)器是線程隔離的數(shù)據(jù)區(qū)。

        Java官方定義: http://www.98ki.com/servlet/HomeServlet?method=get&id=53

        Java各內(nèi)存區(qū)域分析: http://www.98ki.com/servlet/HomeServlet?method=get&id=43

        通過(guò)分析各個(gè)區(qū)域的內(nèi)容我們分別寫出各個(gè)區(qū)域的內(nèi)存溢出實(shí)例

        堆溢出

        由Java的官方文檔我們可以看出,Java堆中存放:對(duì)象、數(shù)組。下面以不斷創(chuàng)建對(duì)象為例:

        Exception in thread "main"java.lang.OutOfMemoryError: Java heap space

        public class HeapLeak {

        public static void main(String[] args){

        ArrayList list = new ArrayList ();

        while ( true ){

        list.add( new HeapLeak.method()) ;

        }

        }

        static class method{

        }

        }

        棧溢出

        從Java官方API中我們知道,棧中存儲(chǔ):基本數(shù)據(jù)類型,對(duì)象引用,方法等。下面以無(wú)限遞歸創(chuàng)建方法和申請(qǐng)??臻g為例,分別演示棧的stackOverflow和OutOfMemory

        l Exception in thread "main" java.lang.StackOverflowError

        package Memory;

        public class StackLeak {

        public static void main(String[] args){

        method ();

        }

        public static void method (){

        method ();

        }

        }

        l Exception in thread "main"java.lang.OutOfMemoryError: unable to create new native thread

        package Memory;

        public class StackOutOfMemory {

        public static int count = 1;

        public void noStop() {

        while ( true ) {

        }

        }

        public void newThread() {

        while ( true ) {

        Thread t = new Thread( new Runnable() {

        public void run() {

        System. out .println( " 已創(chuàng)建第 " + count +++ " 個(gè)線程 " );

        noStop();

        }

        });

        t.start();

        }

        }

        public static void main(String[] args){

        new StackOutOfMemory().newThread();

        }

        }

        Java hotspot虛擬機(jī)中一個(gè)線程占用內(nèi)存可通過(guò)-Xss設(shè)置,而能創(chuàng)建的線程數(shù)計(jì)算方法為:

        可創(chuàng)建線程數(shù)=(物理內(nèi)存-Os預(yù)留內(nèi)存-堆內(nèi)存-方法區(qū)內(nèi)存)/單個(gè)線程大小

        在測(cè)試的時(shí)候這里還有點(diǎn)小插曲,電腦強(qiáng)關(guān)了一次,因?yàn)榘?Xss設(shè)置成了2M,內(nèi)存使用增加到97%左右,操作系統(tǒng)死了,這個(gè)進(jìn)程不斷在創(chuàng)建線程,但是并沒(méi)有因?yàn)閮?nèi)存不足而停下來(lái),直到電腦完全死掉也沒(méi)有報(bào)出錯(cuò)誤信息。最后分析是因?yàn)殡娔X空閑內(nèi)存還有600M,在線程還沒(méi)有創(chuàng)建完的時(shí)候,已經(jīng)開啟的線程太多,在死之前大概能開到200多個(gè),對(duì)內(nèi)存大量消耗,造成系統(tǒng)掛掉。

        這里又出現(xiàn)一個(gè)有趣的現(xiàn)象,當(dāng)線程順序創(chuàng)建到第88個(gè)的時(shí)候,count跳了很多,并且開始無(wú)序,有興趣的可以深入學(xué)習(xí)一下線程方面的問(wèn)題,我也會(huì)在后面的博客分析這個(gè)問(wèn)題。

        而換成200M的時(shí)候,創(chuàng)建第二個(gè)線程的時(shí)候就報(bào)了OutOfMemory.不管Xss設(shè)置多少,報(bào)錯(cuò)之后,程序都會(huì)一直走下去,執(zhí)行已開線程中的任務(wù)。

        常量池溢出

        從Java官方API中我們知道,常量區(qū)代表運(yùn)行時(shí)每個(gè)class文件中的常量表。它包括幾種常量:編譯期的數(shù)字常量、方法或者域的引用(在運(yùn)行時(shí)解析)。runtime constant pool的功能類似于傳統(tǒng)編程語(yǔ)言的符號(hào)表,盡管它包含的數(shù)據(jù)比典型的符號(hào)表要豐富的多。

        下面以不斷添加Stirng為例:

        Exception in thread "main"java.lang.OutOfMemoryError: PermGen space

        常量池在方法區(qū)中,首先設(shè)置持久代大小,使其不可擴(kuò)展。

        然后需要做的就不停地往方法區(qū)中加字符串。其中intern()就是查看方法區(qū)中有沒(méi)有這個(gè)字符串,沒(méi)有的話就加進(jìn)去,如果這里不用intern(),字符串是存在堆里的,會(huì)報(bào)heapOutOfMemory.

        這里需要注意的是,在 HotSpot 中,方法區(qū)是在堆的持久代中的。

        package Memory;

        import java.util.ArrayList;

        public class ConstantPoolLeak {

        public static void main(String[] args) {

        int count = 0;

        ArrayList list = new ArrayList ();

        while ( true )

        list.add(String. valueOf (count++).intern()) ;

        }

        }

        方法區(qū)溢出

        從Java官方API中我們知道,方法區(qū)存放每個(gè)Class的結(jié)構(gòu),比如說(shuō)運(yùn)行時(shí)常量池、域、方法數(shù)據(jù)、方法體、構(gòu)造函數(shù)、包括類中的專用方法、實(shí)例初始化、接口初始化。

        Java的反射和動(dòng)態(tài)代理可以動(dòng)態(tài)產(chǎn)生Class,另外第三方的CGLIB可以直接操作字節(jié)碼,也可以動(dòng)態(tài)產(chǎn)生Class,下面通過(guò)CGLIB來(lái)演示。

        import java.lang.reflect.Method;

        public class MethodAreaLeak {

        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();

        }

        }

        class OOMObject{

        }

        }

        本機(jī)直接內(nèi)存溢出

        Java虛擬機(jī)可以通過(guò)參數(shù)-XX:MaxDirectMemorySize設(shè)定本機(jī)直接內(nèi)存可用大小,如果不指定,則默認(rèn)與java堆內(nèi)存大小相同。JDK中可以通過(guò)反射獲取Unsafe類(Unsafe的getUnsafe()方法只有啟動(dòng)類加載器Bootstrap才能返回實(shí)例)直接操作本機(jī)直接內(nèi)存。通過(guò)使用-XX:MaxDirectMemorySize=10M,限制最大可使用的本機(jī)直接內(nèi)存大小為10MB,例子代碼如下

        package Memory;

        import java.lang.reflect.Field;

        public class DirectMemoryOOM {

        private static final int _1MB = 1024 * 1024 * 1024;

        public static void main(String[] args) throws Exception {

        Field unsafeField = Unsafe . class .getDeclaredFields()[0];

        unsafeField.setAccessible( true );

        Unsafe unsafe = ( Unsafe ) unsafeField.get( null );

        while ( true ) {

        // unsafe 直接想操作系統(tǒng)申請(qǐng)內(nèi)存

        unsafe.allocateMemory( _1MB );

        }

        }

        }

        相關(guān)閱讀推薦

      看了java內(nèi)存溢出如何產(chǎn)生文章內(nèi)容的人還看:

      1.java讀取大文件內(nèi)存溢出怎么解決

      2.java和多線程cpu

      3.內(nèi)存溢出和內(nèi)存泄漏是什么

      4.網(wǎng)絡(luò)安全技術(shù)的探討論文

      5.iphone怎么擴(kuò)大內(nèi)存

      6.JAVA面試題大全及答案

      java內(nèi)存溢出如何產(chǎn)生

      Java是由Sun Microsystems公司推出的Java面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言(以下簡(jiǎn)稱Java語(yǔ)言)和Java平臺(tái)的總稱。下面是學(xué)習(xí)啦小編帶來(lái)的關(guān)于java內(nèi)存溢出如何產(chǎn)生的內(nèi)容,歡迎閱讀! java內(nèi)存溢出如何產(chǎn)生: java虛擬機(jī)規(guī)范規(guī)定的java虛擬機(jī)內(nèi)存其實(shí)
      推薦度:
      點(diǎn)擊下載文檔文檔為doc格式

      精選文章

      • java內(nèi)存溢出怎么解決
        java內(nèi)存溢出怎么解決

        Java是一種可以撰寫跨平臺(tái)應(yīng)用程序的面向?qū)ο蟮某绦蛟O(shè)計(jì)語(yǔ)言。下面是學(xué)習(xí)啦小編帶來(lái)的關(guān)于java 內(nèi)存溢出怎么解決的內(nèi)容,歡迎閱讀! java 內(nèi)存溢出怎么解

      • itools蘋果4內(nèi)存怎么清理
        itools蘋果4內(nèi)存怎么清理

        iPhone 4是結(jié)合照相手機(jī)、個(gè)人數(shù)碼助理、媒體播放器以及無(wú)線通信設(shè)備的掌上設(shè)備,i下面是學(xué)習(xí)啦小編帶來(lái)的關(guān)于itools蘋果4內(nèi)存怎么清理的內(nèi)容,歡迎閱讀

      • ipone6內(nèi)存夠用嗎
        ipone6內(nèi)存夠用嗎

        蘋果公司(Apple Inc. )是美國(guó)的一家高科技公司。由史蒂夫喬布斯、斯蒂夫沃茲尼亞克和羅韋恩(Ron Wayne)等三人于1976年4月1日創(chuàng)立,下面是學(xué)習(xí)啦小編帶來(lái)的關(guān)

      • iphone怎么刪除內(nèi)存
        iphone怎么刪除內(nèi)存

        蘋果公司(Apple Inc. )是美國(guó)的一家高科技公司。由史蒂夫喬布斯、斯蒂夫沃茲尼亞克和羅韋恩(Ron Wayne)等三人于1976年4月1日創(chuàng)立,下面是學(xué)習(xí)啦小編帶來(lái)的關(guān)

      672012