java内存区域与内存溢出异常的详细介绍
java内存区域与内存溢出异常
一、运行时数据区域
1.程序计数器:线程私有,用于存储当前所执行的指令位置
2.Java虚拟机栈:线程私有,描叙Java方法执行模型;执行方法时都会创建一个栈帧,存储局部变量,基本类型变量,引用等信息
3.Java本地方法栈:线程私有,为虚拟机使用到的Native方法服务
4.Java堆:线程共享,是垃圾收集器的主要工作地方;存储对象实例等
5.方法区:线程共享;存储类信息,常量,静态变量等
运行时常量:存放编译时生成的各种字面量和符号引用
6.直接内存:机器的内存
二、虚拟机对象
1.对象的创建
先检查常量池能否定位到此类的符号引用,并检查类是否已经加载初始化,否则要先执行加载过程;
为对象分配内存:计算空间并从堆中划分一块连续或不连续的区域;使用的是cas+失败重试,避免线程安全问题(因为对象创建十分频繁,不知道当前内存有没有被分配出去)
初始化内存空间:将分配的内存空间初始化0值
设置对象基本信息:元数据、hash码、gc等
执行java的init初始化:
2.对象的内存布局
对象头:存储对象的hash码、锁状态等 和 类型指针(对象所指向类的元数据)
实例数据:对象真正存储的信息
对齐填充:填充符合规则
3.对象的访问定位
对象的访问,通过java栈上的reference数据,它维护了一个指向对象的引用
访问方式:句柄和直接访问
句柄:堆中维护句柄池,reference指向句柄,句柄中包含了对象实例数据和类型数据的地址信息
移动方便,直接修改句柄中的实例数据即可;开销大,多了一次指针定位
直接:reference直接指向对象地址
速度快
三、实战OutofMemoryERROR
1.java堆溢出
参数:-Xms堆最小值;-Xmx堆最大值;-XX:+HeapDumpOnOutOfMemoryError出现溢出时内存快照分析
堆中存放的是对象:可以创建大量对象来实现堆溢出:heap space
2.栈溢出
参数:-Xss设置栈值
栈深度,可以通过无限递归增加栈深度、或创建大量线程实现
//递归来StackOverFlowerpublic class JavaVMStackSOF {private int stackLength = 1;public void stackLeak(){ stackLength++; stackLeak(); }public static void main(String[] args)throws Throwable{ JavaVMStackSOF oom = new JavaVMStackSOF();try { oom.stackLeak(); } catch(Throwable e){ System.out.println("stack length:" + oom.stackLength);throw e; } } }
3.方法区和常量池溢出
参数:-XX:PermSize方法区大小;-XX:MaxPermSize方法区最大大小
在JDK1.6前,可以通过创建大量的String,虚拟机会复制对象放入常量池,从而溢出
在1.7及以后,不可以这样,因为虚拟机只会在常量池中保存首次出现此对象时对象的引用
方法区的溢出:方法区保存的是类的信息,通过产生大量的动态类来溢出,如spring其实也是通过动态代理产生的类
public class JavaMethodAreaOOM{public static void main(String[]args){while(true){//创建大量的动态类,动态代理OOMObjectEnhancer 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(); }}static class OOMObject{ } }
String.intern()是一个Native方法,它的作用是:如果字符串常量池中已经包含一个等于此String对象的字符串,则返回代表池中这个字符串的String对象;否则,将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用
JDK6及以前:方法区(永久代)是单独的,常量池在方法区内
JDK7:去永久代
public class RuntimeConstantPoolOOM{public static void main(String[]args){ String str1=new StringBuilder("计算机").append("软件").toString(); System.out.println(str1.intern()==str1); String str2=new StringBuilder("ja").append("va").toString(); System.out.println(str2.intern()==str2); } }
这段代码在JDK 1.6中运行,会得到两个false,而在JDK 1.7中运行,会得到一个true和一个false。
产生差异的原因是:在JDK 1.6中,intern()方法会把首次遇到的字符串实例复制到永久代中,返回的也是永久代中这个字符串实例的引用,而由StringBuilder创建的字符串实例在Java堆上,所以必然不是同一个引用,将返回false。
而JDK 1.7:intern()实现不会再复制实例,只是在常量池中记录首次出现的实例引用,因此intern()返回的引用和由StringBuilder创建的那个字符串实例是同一个。
对str2比较返回false是因为“java”这个字符串在执行StringBuilder.toString()之前已经出现过,字符串常量池中已经有它的引用了,不符合“首次出现”的原则,而“计算机软件”这个字符串则是首次出现的,因此返回true
注意:1.7及以后保存的是首次出现的引用;理解上面的分析
4.本机直接内存
参数:-XX:MaxDirectMemorySize直接内存大小;默认==最大堆内存
Atas ialah kandungan terperinci java内存区域与内存溢出异常的详细介绍. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas





Java 8 memperkenalkan API Stream, menyediakan cara yang kuat dan ekspresif untuk memproses koleksi data. Walau bagaimanapun, soalan biasa apabila menggunakan aliran adalah: bagaimana untuk memecahkan atau kembali dari operasi foreach? Gelung tradisional membolehkan gangguan awal atau pulangan, tetapi kaedah Foreach Stream tidak menyokong secara langsung kaedah ini. Artikel ini akan menerangkan sebab -sebab dan meneroka kaedah alternatif untuk melaksanakan penamatan pramatang dalam sistem pemprosesan aliran. Bacaan Lanjut: Penambahbaikan API Java Stream Memahami aliran aliran Kaedah Foreach adalah operasi terminal yang melakukan satu operasi pada setiap elemen dalam aliran. Niat reka bentuknya adalah

Platform Perdagangan Mata Wang Mata Wang Mata Wang Mata Wang Mata Tinggi: 1. Coinbase, pertukaran utama di Amerika Syarikat, mudah digunakan pematuhan;

Kapsul adalah angka geometri tiga dimensi, terdiri daripada silinder dan hemisfera di kedua-dua hujungnya. Jumlah kapsul boleh dikira dengan menambahkan isipadu silinder dan jumlah hemisfera di kedua -dua hujungnya. Tutorial ini akan membincangkan cara mengira jumlah kapsul yang diberikan dalam Java menggunakan kaedah yang berbeza. Formula volum kapsul Formula untuk jumlah kapsul adalah seperti berikut: Kelantangan kapsul = isipadu isipadu silinder Dua jumlah hemisfera dalam, R: Radius hemisfera. H: Ketinggian silinder (tidak termasuk hemisfera). Contoh 1 masukkan Jejari = 5 unit Ketinggian = 10 unit Output Jilid = 1570.8 Unit padu menjelaskan Kirakan kelantangan menggunakan formula: Kelantangan = π × r2 × h (4

Java ialah bahasa pengaturcaraan popular yang boleh dipelajari oleh pembangun pemula dan berpengalaman. Tutorial ini bermula dengan konsep asas dan diteruskan melalui topik lanjutan. Selepas memasang Kit Pembangunan Java, anda boleh berlatih pengaturcaraan dengan mencipta program "Hello, World!" Selepas anda memahami kod, gunakan gesaan arahan untuk menyusun dan menjalankan program, dan "Hello, World!" Pembelajaran Java memulakan perjalanan pengaturcaraan anda, dan apabila penguasaan anda semakin mendalam, anda boleh mencipta aplikasi yang lebih kompleks.

Spring Boot memudahkan penciptaan aplikasi Java yang mantap, berskala, dan siap pengeluaran, merevolusi pembangunan Java. Pendekatan "Konvensyen Lebih Konfigurasi", yang wujud pada ekosistem musim bunga, meminimumkan persediaan manual, Allo

PHP dan Python masing -masing mempunyai kelebihan sendiri, dan pilihannya harus berdasarkan keperluan projek. 1.Php sesuai untuk pembangunan web, dengan sintaks mudah dan kecekapan pelaksanaan yang tinggi. 2. Python sesuai untuk sains data dan pembelajaran mesin, dengan sintaks ringkas dan perpustakaan yang kaya.

PHP adalah bahasa skrip yang digunakan secara meluas di sisi pelayan, terutamanya sesuai untuk pembangunan web. 1.PHP boleh membenamkan HTML, memproses permintaan dan respons HTTP, dan menyokong pelbagai pangkalan data. 2.PHP digunakan untuk menjana kandungan web dinamik, data borang proses, pangkalan data akses, dan lain -lain, dengan sokongan komuniti yang kuat dan sumber sumber terbuka. 3. PHP adalah bahasa yang ditafsirkan, dan proses pelaksanaan termasuk analisis leksikal, analisis tatabahasa, penyusunan dan pelaksanaan. 4.Php boleh digabungkan dengan MySQL untuk aplikasi lanjutan seperti sistem pendaftaran pengguna. 5. Apabila debugging php, anda boleh menggunakan fungsi seperti error_reporting () dan var_dump (). 6. Mengoptimumkan kod PHP untuk menggunakan mekanisme caching, mengoptimumkan pertanyaan pangkalan data dan menggunakan fungsi terbina dalam. 7

Java Made Simple: Panduan Permulaan untuk Kuasa Pengaturcaraan Pengenalan Java ialah bahasa pengaturcaraan berkuasa yang digunakan dalam segala-galanya daripada aplikasi mudah alih hingga sistem peringkat perusahaan. Untuk pemula, sintaks Java adalah ringkas dan mudah difahami, menjadikannya pilihan ideal untuk pembelajaran pengaturcaraan. Sintaks Asas Java menggunakan paradigma pengaturcaraan berorientasikan objek berasaskan kelas. Kelas ialah templat yang menyusun data dan tingkah laku yang berkaitan bersama-sama. Berikut ialah contoh kelas Java yang mudah: publicclassPerson{privateStringname;privateintage;
