jvm

关于JVM案例分析(一)

血红的双手。 提交于 2020-02-10 15:36:40
准备模拟内存泄漏样例 1、定义静态变量HashMap 2、分段循环创建对象,并加入HashMap 代码如下: import java.util.HashMap; import java.util.Map; public class CyclicDependencies { //声明缓存对象 private static final Map map = new HashMap(); public static void main(String args[]){ try { Thread.sleep(10000);//给打开visualvm时间 } catch (InterruptedException e) { e.printStackTrace(); } //循环添加对象到缓存 for(int i=0; i<1000000;i++){ TestMemory t = new TestMemory(); map.put("key"+i,t); } System.out.println("first"); //为dump出堆提供时间 try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } for(int i=0; i<1000000;i++){ TestMemory t =

JAVA 项目启动 JVM 生产环境 CMS 参数设置参考

寵の児 提交于 2020-02-10 11:10:18
参数设置如下: nohup $JAVA_HOME/bin/java $exec_command > $log 2>&1 < /dev/null & -server -Xmx16g -Xms4g -Xss512k -XX:+DisableExplicitGC // 禁止代码中显示调用GC -XX:+UseConcMarkSweepGC // 使用 CMS 收集器 -XX:+CMSParallelRemarkEnabled // 开启了降低标记停顿 -XX:LargePageSizeInBytes=128m // 使用大的内存分页 -XX:+UseFastAccessorMethods // 原始类型的快速优化 -XX:+UseCMSInitiatingOccupancyOnly // 使用手动定义初始化定义开始CMS收集 -XX:CMSInitiatingOccupancyFraction=70 // 当老年代达到70%时,触发CMS垃圾回收 -classpath xxxx:xxxx $CLASS 来源: CSDN 作者: 张伯毅 链接: https://blog.csdn.net/zhanglong_4444/article/details/104244332

JVM——垃圾收集算法

给你一囗甜甜゛ 提交于 2020-02-10 07:15:29
1.标记-清除算法   最基础的收集算法,如其名,算法为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。   两个不足:     1)效率问题,标记和清除两个过程的效率多不高;     2)空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。 2.复制算法   这种算法是为了解决效率的问题。它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。这样使得每次都是对整个半区进行内存回收,内存分配时也就不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。   但是这种算法的代价是将内存缩小为了原来的一半,有点高了。。 3.标记-整理算法   复制收集算法在对象存活率较高时就要进行较多的复制操作,效率将会变低。更关键的是,如果不想浪费一半的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都全部存活的极端情况,所以在老年代一般不能直接选用这种算法。   根据老年代的特点,有人提出了另外一种“标记-整理”算法,标记过程仍然与“标记-清除”算法一样

森度

对着背影说爱祢 提交于 2020-02-10 01:20:11
JDK和JRE JDK(Java Development Kit):java开发软件工具包,用java做开发时必须使用JDK JRE(Java Runtime Environment):java最小运行时环境,运行一个已编译好的java程序时需要用到JRE JDK包括:java语言、JVM、javaApi(jdbc、javadoc、javac、String、IO等等) JRE包括:JVM、javaApi中的一部分(不包括javac、javadoc等编译、调试工具) JVM内存划分 我们运行的每个类和线程都有很多信息需存储在JVM中,比如常量、对象、类信息等,JVM为这些信息分配了不同的内存区域。就像商品会归类存放到对应的货仓,生鲜仓、干货仓等等。 JVM规范将内存区域划分情况如下图: 如何配置各个内存区域的大小 堆 -Xms最小值,-Xmx最大值,-Xmn新生代大小。-XX:SurvivorRatio=8表示 方法区 -XX:PermSize最小值,-XX:MaxPermSize最大值 栈 -Xss每个线程的栈大小 用例子来讲解 例子A 1 Object a = new Object(); 这一行代码的存储情况,如下 操作数栈:计算时,存储计算过程的临时存储区域 常量池存放最多的是常量值和符号引用,符号引用:类和接口的全限定名;字段的名称和描述符;方法和名称和描述符 例子B

JVM类加载机制

点点圈 提交于 2020-02-10 01:17:25
个人博客 http://www.milovetingting.cn JVM类加载机制 前言 本文为学习Java相关知识所作笔记,参考以下资料: https://github.com/Snailclimb/JavaGuide ,感谢原作者的分享! JVM 类加载机制 JVM 类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程。 加载 加载是类加载过程中的一个阶段,这个阶段会在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类的各种数据的入口。注意这里不一定非得要从一个 Class 文件获取,这里既可以从 ZIP 包中读取(比如从 jar 包和 war 包中读取),也可以在运行时计算生成(动态代理),也可以由其它文件生成(比如将 JSP 文件转换成对应的 Class 类)。 验证 这一阶段的主要目的是为了确保 Class 文件的字节流中包含的信息是否符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。 准备 准备阶段是正式为类变量分配内存并设置类变量的初始值阶段,即在方法区中分配这些变量所使用的内存空间。注意这里所说的初始值概念,比如一个类变量定义为: public static int v = 8080; 实际上变量 v 在准备阶段过后的初始值为 0 而不是 8080,将 v 赋值为 8080 的 put

JVM内存模型

寵の児 提交于 2020-02-10 00:57:43
个人博客 http://www.milovetingting.cn JVM内存模型 前言 本文为学习Java相关知识所作笔记,参考以下资料: https://github.com/Snailclimb/JavaGuide ,感谢原作者的分享! 基本概念 JVM是可运行Java代码的虚拟计算机,包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收器、堆和一个存储方法域。JVM运行在操作系统之上,它与硬件没有直接交互。 Java源文件,通过编译器,能够生产相应的class文件,也就是字节码文件,字节码文件通过Java虚拟机中的解释器,编译成特定机器上的机器码。 Java源文件-->编译器-->字节码文件 字节码文件-->JVM-->机器码 每一种平台的解释器是不同的,但是实现的虚拟机是相同的,这也就是 Java 为什么能够跨平台的原因了 ,当一个程序从开始运行,这时虚拟机就开始实例化了,多个程序启动就会存在多个虚拟机实例。程序退出或者关闭,则虚拟机实例消亡,多个虚拟机实例之间数据不能共享。 线程 这里所说的线程指程序执行过程中的一个线程实体。JVM 允许一个应用并发执行多个线程。Hotspot JVM 中的 Java 线程与原生操作系统线程有直接的映射关系。当线程本地存储、缓冲区分配、同步对象、栈、程序计数器等准备好以后,就会创建一个操作系统原生线程。Java 线程结束

记一次OutOfMemoryError: unable to create new native thread

蹲街弑〆低调 提交于 2020-02-09 23:12:49
前言 今天在测试环境跑测试用例的时候发现一大片测试用例无法通过,查看日志发现 OutOfMemoryError: unable to create new native thread 。从日志信息来看,很明显,内存不足,无法创建本地线程。 遇到这个异常还是很意外的,测试用例大概就1.5k个,不至于跑个用例就来这么个异常,测试环境当时jvm的内存是4g,感觉不至于出现这个问题。(当然觉得意外的原因还是对jvm线程数量限制的理解有误) 要解决问题,首先,还是的了解jvm的线程数量到底受限哪些因素。 jvm线程数量限制 jvm线程受限于操作系统可用内存还是JVM的内存 1. Java线程的实现是基于底层系统的线程机制来实现的 ,程序中开的线程并不全部取决于JVM虚拟机栈,而是取决于CPU,操作系统,其他进程,Java的版本。JVM的线程与计算机本身性能相关。 这个很重要,不了解这一点,很容易像我之前一样误解为jvm线程个数首先于jvm的内存大小。 JVM线程的栈在64位Linux操作系统上的默认大小是多少 不显式设置-Xss或- XX:ThreadStackSize 时,在Linux x64上 ThreadStackSize 的默认值就是1024KB,给Java线程创建栈会用这个参数指定的大小。这是前一块代码的意思。如果把- Xss 或者 -XX:ThreadStackSize 设为0

myeclipse优化配置

烂漫一生 提交于 2020-02-09 17:48:30
很多人都感觉myeclipse机子启动速度太慢,那是因为里面集成了太多的功能,但对于大多数人来说是不必要的,只需要根据自己正在用的项目加载相应的工具就行了。等到用到其他的时候再加载需要的。 <1> Myeclipse的安装目录下面有个名为eclipse.ini的文件, 用记事本打开后, 修改参数: 把-Xms128m改成-Xms256m 把-Xmx256m改成-Xmx512m <2> 去除不需要加载的模块Windows - Preferences --> General--> Startup and Shutdown 这时右侧就 显示出了Eclipse启动时加载的模块,根据需要去除一些模块。 <3>取消启动时自动验证项目配置文件 Window -> Preferences -> MyEclipse Enterprise Workbench-> Run Validation 在右侧的Validator列表中只保留 Manual 项就可以了 如果需要验证的时候只需要选中 文件,然后右键选择 MyEclipse - Run Validation就可以了 我机子的优化修改 1. Windows - Preferences --> General--> Startup and Shutdown原来自己机子上面启动很慢,但是现 在很快,因为几乎去掉了这里面所有不该启动地项目加载。 2

多图:一文带你入门掌握JVM所有知识点

别说谁变了你拦得住时间么 提交于 2020-02-09 10:45:45
本JVM系列属于本人学习过程当中总结的一些知识点,目的是想让读者更快地掌握JVM相关的知识要点,难免会有所侧重,若想要更加系统更加详细的学习JVM知识,还是需要去阅读专业的书籍和文档。 本文主题内容: JVM 内存区域概览 堆区的空间分配是怎么样?堆溢出的演示 创建一个新对象内存是怎么分配的? 方法区 到 Metaspace 元空间 栈帧是什么?栈帧里有什么?怎么理解? 本地方法栈 程序计数器 Code Cache 是什么? 注:请 区分 JVM内存结构(内存布局) 和 JMM(Java内存模型)这两个不同的概念! 概览 内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的实时运行。JVM 内存布局规定了 Java 在运行过程中内存申请、分配、管理的策略 ,保证了 JVM 的高效稳定运行。 上图描述了当前比较经典的Java内存布局。(堆区画小了2333,按理来说应该是最大的区域) 如果按照线程是否共享来分类的话,如下图所示: PS:线程是否共享这点,实际上理解了每块区域的实际用处之后,就很自然而然的就记住了。不需要死记硬背。 下面让我们来了解下各个区域。 一、Heap (堆区) 1.1 堆区的介绍 我们先来说堆。堆是 OOM故障最主要的发生区域。它是内存区域中最大的一块区域,被所有线程共享,存储着几乎所有的实例对象、数组

2. Java程序的运行机制

 ̄綄美尐妖づ 提交于 2020-02-09 08:20:26
一、完成一个Java程序的流程:编辑Java源代码→编译Java程序→运行Java程序 1. 在记事本中编写Java程序,然后保存为 .java类型文件(Java源文件) 2. 使用javac命令将源文件编译成 字节码文件(*.class文件) 3. 使用java命令解释执行字节码文件 【示例】 1. 在路径D:\下创建一个HelloWorld.java文件,并编写如下代码 public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } } 2. 在命令行窗口先切换到路径D:\,然后输入“javac [-d .] HelloWorld.java”命令 补:javac命令的用法为“ javac -d destdir srcFile ”,其中“-d destdir”指定编译生成的字节码文件的存放路径,而srcFile则是Java源文件所在的位置。 3. 在命令行窗口进入HelloWorld.class所在的位置,然后输入“java HelloWorld”命令 补:java命令的用法为“ java Java类名 ”,java命令后的参数是Java类名,而不是字节码文件的文件名,也不是Java源文件名。 二、Java程序的运行原理