JVM从入门到放弃——JVM内存模型

前言

Java和C或者是C++相比较而言,最大的区别是C系列的程序员在编写代码的时候,总是要对程序中的变量进行释放内存的操作,所以在编写C或者是C++的程序员需要格外的谨慎,因为他们对程序的内存有着很高的权限,这样虽然是特点但是同时也是缺点,毕竟every coin has two sides。所以跟Java语言相比而言,Java把内存的管理直接交付给JVM,因为JVM的存在,Java程序员能够更关注业务的实现,而不需要对内存的管理过于关注。但是我们在编程的时候,有时候会出现OutOfMemoryError之类的错误,这就是JVM内存溢出的错误。这样如果我们对Java虚拟机对内存的管理,我们就不能很好的解决类似的问题,所以我们还是要对Java的内存管理要有一定的理解,对我们后期对Java代码调优也是有一定的帮助。

Java虚拟机内存模型

这里写图片描述 
根据上图可以看出来JVM的运行时数据区域主要就是方法区,虚拟机栈,虚拟机堆内存,本地方法区和程序计数器。下面就来看看这些个内存区域都是用来存储哪些数据的。

Java虚拟机栈

方法区是线程私有的内存区域,声明周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型,每个方法执行的时候,虚拟机会以栈帧的形式压入到栈中,这里的栈也是一种先进后出的数据结构。栈帧通常是用来存储局部变量表,操作数栈,帧数据区等信息。每个方法的调用和结束都是入栈和出栈的操作。由于每次方法的调用都会生成对应的栈帧,栈帧会占用一定的栈空间,因此,如果栈帧的空间不足,函数的调用就无法进行下去,当请求的栈的深度大于最大的可用栈深度的时候,系统就会抛出StackOverflowError的溢出错误。 
局部变量表存放编译期可以知道的各种基本数据类型(boolean,byte,char,short,int,float,long,double),对象引用和returnAddress类型。其中64位长度的long和double类型的数据会占用2个slot局部变量空间,其余的都是一个slot。局部变量表所需要的内存空间在编译期间完成分配,运行期间不会改变局部变量表的大小。 
代码实现StackOverflowError的溢出错误

package com.jvm.method_region;public class MethodRegionTest {Integer count = 0;public void method1() { count ++; method1(); } public static void main(String[] args) { MethodRegionTest methodRegionTest = null; try { methodRegionTest = new MethodRegionTest(); methodRegionTest.method1(); }catch (Exception e) { // TODO: handle exception }finally { System.out.println("递归java栈的深度是 : " + methodRegionTest.count);

在运行的时候,修改JVM参数,通过修改-Xss128K可以改变虚拟机栈的大小,我第一次是128K第二次是256K,看执行的结果

递归java栈的深度是 : 994
Exception in thread "main" java.lang.StackOverflowError at java.lang.Integer.<init>(Unknown Source) at java.lang.Integer.valueOf(Unknown Source) at com.jvm.method_region.MethodRegionTest.method1(MethodRegionTest.java:8) at com.jvm.method_region.MethodRegionTest.method1(MethodRegionTest.java:9) at com.jvm.method_region.MethodRegionTest.method1(MethodRegionTest.java:9) at com.jvm.method_region.MethodRegionTest.method1(MethodRegionTest.java:9) at com.jvm.method_region.MethodRegionTest.method1(MethodRegionTest.java:9)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

第二次

递归java栈的深度是 : 2475
Exception in thread "main" java.lang.StackOverflowError at java.lang.Integer.<init>(Unknown Source) at java.lang.Integer.valueOf(Unknown Source) at com.jvm.method_region.MethodRegionTest.method1(MethodRegionTest.java:8) at com.jvm.method_region.MethodRegionTest.method1(MethodRegionTest.java:9) at com.jvm.method_region.MethodRegionTest.method1(MethodRegionTest.java:9) at com.jvm.method_region.MethodRegionTest.method1(MethodRegionTest.java:9) at com.jvm.method_region.MethodRegionTest.method1(MethodRegionTest.java:9) at com.jvm.method_region.MethodRegionTest.method1(MethodRegionTest.java:9)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在eclipse改变JVM的参数操作 
这里写图片描述 
<————————-这是分隔符————————————-> 
这里写图片描述

本地方法栈

本地方法栈和虚拟机栈类似,但是他们也是有区别的,区别就是虚拟机栈是调用java方法的时候,会把栈帧压入栈中,而本地方法栈是调用的native方法,native是由C++编写的。同时本地方法栈也会和虚拟机栈一样也是会爆出来StackOverflowError和OutOfMemoryError的错误。OutOfMemoryError的错误是在虚拟机的栈内存可以自动扩展的情况下,不停的将栈帧数据压入到栈中,以至于虚拟机不停的申请内存,最后导致内存的溢出,所以爆出来OutOfMemoryError错误。

虚拟机堆

Java Heap是Java虚拟机所管理的内存最大的一块,这一块的内存区域是所有线程共享的。此内存区域是用来存放对象实例,几乎所有的对象实例以及数组都在这里分配内存。Java Heap还可以细分为新生代区和老年代区,而新生代区还可以分为eden区,from区和to区,from和to的大小是一样的。在绝大数的情况下,对象是先分配在eden区,在第一次垃圾回收后,如果对象还存活着,那么该对象就会进入到from区或者是to区,然后每经过一次垃圾回收,对象依然存活着,它的年纪就会增加1。当对象的年纪到达一定的条件后,该对象就会进入到老年tenured区。

程序计数器

Program Counter是每个线程的私有空间,Java虚拟机会为每一个线程创建PC寄存器,在任意时刻,一个线程总是在执行一个方法,正在执行的方法称为当前方法。如果当前方法不是本地方法,PC寄存器就会指向当前正在被执行的指令。如果当前方法是本地方法,那么PC寄存器的值就是undefined。

方法区

方法区也是线程共享的内存区域,用于保存系统的类信息,比如类的字段,方法,常量池等,方法区的大小决定了系统可以保存多少个类如果系统定义了太多的类,同样会导致方法区的溢出。在JDK1.6和JDK1.7中,方法区可以理解为永久区(Perm)。永久区可以使用参数-XX:PermSize和-XX:MaxPermSize指定,默认情况下,-XX:MaxPermSize为64MB。一个大的永久区可以保存更多的信息。如果系统中使用一些动态代理,那么就有可能在运行时生成大量的类。在JDK1.8中,永久区已经被彻底移除,用元数据区来代替。元数据区可以使用-XX:MaxMetaspaceSize指定,元数据区使用的系统的直接内存。如果不指定元数据的大小,程序会耗尽所有的内存。

package com.jvm.perm;import net.sf.cglib.beans.BeanGenerator;public class PermTest { class Perm{ String name; public String getName(www.bomaoyule.cn) { return name; } public void setName(String name) { this.name = name; } } public static void main(String[www.yingka178.com ] args) { try { for (int i = 0; i < 1000000; i++) { BeanGenerator generator = new BeanGenerator(www.078881.cn ); generator.setSuperclass(Perm.class); generator.addProperty("name", String.class); generator.create(www.chaoyueyule.com/); } } catch (Exception www.dongfan178.com e) www.mcyllpt.com/ { // TODO: handle exception

加了虚拟机参数-XX:+PrintGCDetails -XX:MaxMetaspaceSize=256k 
运行结果

Error occurred during initialization of VM
OutOfMemoryError: Metaspace

转载于:https://www.cnblogs.com/qwangxiao/p/9249586.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/570672.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

485. Max Consecutive Ones - LeetCode

Question 485. Max Consecutive Ones Solution 题目大意:给一个数组,取连续1的最大长度 思路:遍历数组,连续1就加1,取最大 Java实现: public int findMaxConsecutiveOnes(int[] nums) {if (nums null) return 0;int result 0;int tmp 0;for (int i : nums) {if (i 1) {tmp;…

MacBook创建docker私有仓库docker server gave HTTP response to HTTPS client 问题处理办法

在 mac上搭建一个私有仓库&#xff0c;在向仓库push镜像时&#xff0c;会报如下错误&#xff1a; #docker push 192.168.163.131:5000/test Get https://192.168.163.131:5000/v1/_ping: http: server gave HTTP response to HTTPS client 百度了下答案发现都不试用mac版本的d…

Redis基础1(定义及基础)

Redis 定义&#xff1a;Redis是一个软件&#xff0c;帮助开发者对一台机器的内存进行操作 安装redis软件方法&#xff1a; 超链接地址&#xff1a;https://www.cnblogs.com/L5251/articles/9146881.html Python中下载依赖包 pip3 install redis 测试Redis是否安装成功 # 1、引入…

vue-cli安装

、安装vue-cli 命令&#xff1a;npm install vue-cli -g -g表示全局安装 2、初始化项目 命令&#xff1a;vue init webpack my-project 使用vue命令初始化项目&#xff0c;并使用webpack打包 此时会跳出一系列问题&#xff0c;除了eslint那一项&#xff0c;其余的均可回答yes&a…

修复病毒破坏的文件关联并恢复程序图标

1.破坏文件关联的两种方式&#xff1a; &#xff08;1&#xff09;修改特定扩展名文件的对应名称。以.exe文件为例&#xff1a; 正常注册表中&#xff0c;.exe文件对应名称为&#xff1a; HKEY_CLASSES_ROOT\.exe &#xff08;默认&#xff09; exefile 病毒为…

双击程序后系统弹框“您无权访问此程序”的解决办法

xp下&#xff1a;我的电脑>工具>文件夹选项>查看&#xff0c;勾掉使用简单文件共享选项。如下图&#xff1a; 此时&#xff0c;在右键点击程序图标时&#xff0c;选项卡中会出现“安全”选项卡。如下图&#xff1a; 修改everyone为Administrator...并设置完全控制权限…

adb常用操作命令

1、adb devices 查看当前链接设备&#xff0c;列出连接到计算机的Android设备或者模拟器 2、adb install <apk文件路径> 安装软件 3、adb uninstall <软件名> 卸载apk之前要先查看报名&#xff1a; 知晓包名之后&#xff0c;就可以运用命令卸载该APK 4、adb shell …

轻量级ORM框架 【Dapper】 的使用

ORM是什么&#xff1f; 从字面理解&#xff0c;O是Object&#xff0c;对象&#xff1b;R是Relation&#xff0c;关系&#xff1b;M是Mapping&#xff0c;映射。所以&#xff0c;用一句话概括就是&#xff1a;ORM是一种对象关系映射的技术。 Dapper 是.NET下的一种ORM框架。 Dap…

系统提示一个程序正在被另一个程序调用,如何知道是被哪个程序调用

今天在处理一个病毒时&#xff0c;发现病毒文件无法复制。于是利用processxp找到了病毒文件是被哪个文件调用&#xff0c;然后用md关闭了调用句柄后成功复制文件。具体情况如下&#xff1a; 为了找到是哪个程序调用了befsvc.exe&#xff0c;打开processexplorer.exe&#xff0c…

通过修改explorer.exe内存隐藏文件及注册表项

记录今天分析的一个隐藏自身及注册表项的病毒。 1.概述&#xff1a; &#xff08;1&#xff09;此病毒文件为路径为&#xff1a;C:\Windows7\4D525EC1C14.exe&#xff0c;且注册了自启动项&#xff1a; HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run […

WPF xaml中列表依赖属性的定义

WPF xaml中列表依赖属性的定义 原文:WPF xaml中列表依赖属性的定义列表内容属性 如上图&#xff0c;是一个列表标题排序控件&#xff0c;我们需要定义一个标题列表&#xff0c;从而让调用方可以自由的设置标题信息。 在自定义控件时&#xff0c;会遇到列表依赖属性&#xff0c;…

由于权限问题无法删除注册表键值的解决方法

在中了某个病毒之后手动删除病毒自启动项失败&#xff0c;如下图&#xff1a; 查看run项的权限&#xff0c;发现用户被修改成了Everyone&#xff0c;并且没有任何权限&#xff0c;如下图&#xff1a; 手动赋予Everyone用户完全控制权限后删除注册表项成功&#xff0c;如下图&am…

c++利用windows api遍历指定文件夹及其子文件夹中的文件

以下代码在vs2008中测试通过&#xff0c;利用FindFirstFile,FindNextFile函数遍历了我电脑上全路径为“C:\\Users\\v_tianboli\\Desktop\\windows程式设计开发指南”的文件夹&#xff0c;并输出文件夹及子文件夹中的所有文件完整路径到控制台。完整代码如下&#xff1a; #inclu…

某释放驱动的样本分析及手杀报告

此为样本文件下载链接&#xff1a;http://download.csdn.net/detail/cs08211317dn/3982364&#xff0c;压缩包解压缩密码为&#xff1a;virus。 今天花了1个多小时分析了一款名为123.exe的病毒&#xff0c;觉得挺有意思的&#xff0c;于是顺手写个手杀报告&#xff0c;以备以后…

CentOS 7.2 安装zabbix 3.4

一、zabbix版本选择及部署环境说明 1、zabbix版本选择 zabbix官网地址&#xff1a;www.zabbix.com zabbix每半年发布一个长期支持版&#xff0c;目前长期支持版有2.0、3.0等&#xff0c;所以选择zabbix版本建议选择长期支持版&#xff0c;除非有特殊需求。 2、部署环境环境说明…

吴恩达机器学习笔记(二) —— Logistic回归

主要内容&#xff1a; 一.回归与分类 二.Logistic模型即sigmoid function 三.decision boundary 决策边界 四.cost function 代价函数 五.梯度下降 六.自带求解函数 七.多分类问题 一.回归与分类 回归&#xff1a;用于预测&#xff0c;输出值是连续型的。例如根据房子的大小预测…

弹出选择文件夹的对话框 BROWSEINFO 的用法【MFC】

以下是在vs2008中编译通过的代码&#xff0c;代码注释详细。要实现的功能是点击“浏览”按钮&#xff0c;即弹出选择文件夹的对话框。并将选择的文件夹或文件路径显示在MessageBox中。 void CMFC_TrojanKillerDlg::OnBnClickedButton1() {// TODO: 在此添加控件通知处理程序代码…

regini.exe使用方法

创建一个名称test 类型reg_dword 数据1 如果是只有那会默认以类型reg_sz创建 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\ys test reg_dword 1 2。注册表键数值 [更改的权限] 例如: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run…

计算机寄存器及标志位详解

以下是计算机内部寄存器阵列图&#xff1a; 以下FR控制标志位及其含义&#xff1a; 1. CF 进位标识位 进行加减运算时, 如果最高二进制位产生进位或错位, CF则为1, 否则为0. 程序设计中, 常用条件转移指令JC, JNC指令据此标志位实现转移 2. PF 奇偶标志位 操作结果…

NOIP 2010 引水入城

P1514 引水入城 题目描述 在一个遥远的国度&#xff0c;一侧是风景秀美的湖泊&#xff0c;另一侧则是漫无边际的沙漠。该国的行政区划十分特殊&#xff0c;刚好构成一个 NN 行 \times MM 列的矩形&#xff0c;如上图所示&#xff0c;其中每个格子都代表一座城市&#xff0c;每座…