jvm

JVM中Instrumentation实现

走远了吗. 提交于 2020-03-14 16:49:09
想必不少人听说过javaagent,但是很少人听说Instrumentation,其实Instrumentation就是javaagent的实现机制,说到Instrumentation,就必须想了解java的attach机制,那就先说下attach的实现。 大家进行jstack的时候,是不是经常看到两个线程 Signal Dispatcher 和 Attach Listener 线程,可能不知道是干嘛的吧,这两个线程是实现attach的关键所在,其中 前者是在jvm启动的时候就会创建的 , 后者只有接收过attach请求的时候vm才会创建 ,顾名思义, Signal Dispatcher是分发信号的 , Attach Listener 是处理attach请求的 ,那么两者有什么关系呢,当我们 执行attach方法的时候,会向目标vm发出一个SIGQUIT 的信号,目标vm收到这个信号之后就会创建Attach Listener线程了 ,当然jvm保证了不会多创建。 Attach机制说得简单点就是提供A进程可以连上B进程(当然是java进程),创建socket进行通信,A通过发命令给B,B然后对命令进行截取从自己的vm中获取信息发回给客户端vm,但是并不是随便发指令都会处理的,那么attach Listener接收哪些命令呢,如下所示: static

JVM占用VIRT虚拟内存高问题研究

与世无争的帅哥 提交于 2020-03-14 12:17:27
1. 现象 最近发现线上机器 java 8 进程的 VIRT 虚拟内存使用达到了 11G+,如下图所示: 2. 不管用的 -Xmx 首先第一想到的当然使用 java 的 -Xmx 去限制堆的使用。但是无论怎样设置,都没有什么效果。没办法,只好开始苦逼的研究。 3. 什么是 VIRT 现代操作系统里面分配虚拟地址空间操作不同于分配物理内存。在64位操作系统上,可用的最大虚拟地址空间有16EB,即大概180亿GB。那么在一台只有16G的物理内存的机器上,我也能要求获得4TB的地址空间以备将来使用。例如: void *mem = mmap(0, 4ul * 1024ul * 1024ul * 1024ul * 1024ul, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE , -1, 0); 当使用 mmap 并设置 MAP_NORESERVE 标志时,并不会要求实际的物理内存和swap空间存在。所以上述代码可以在top中看到使用了 4096g 的 VIRT 虚拟内存,这当然是不可能的,它只是表示使用了 4096GB 的地址空间而已。 4. 为什么会用这么多地址空间 那 Java 程序为什么会使用这么多的地址空间呢?使用“pmap -x”来查看一下: … 00007ff638021000 65404

JVM系列三:JVM参数设置、分析

只谈情不闲聊 提交于 2020-03-13 13:33:00
不管是YGC还是Full GC,GC过程中都会对导致程序运行中中断,正确的选择 不同的GC策略 ,调整JVM、GC的参数,可以极大的减少由于GC工作,而导致的程序运行中断方面的问题,进而适当的提高Java程序的工作效率。但是调整GC是以个极为复杂的过程,由于各个程序具备不同的特点,如:web和GUI程序就有很大区别(Web可以适当的停顿,但GUI停顿是客户无法接受的),而且由于跑在各个机器上的配置不同(主要cup个数,内存不同),所以使用的GC种类也会不同(如何选择见 GC种类及如何选择 )。本文将注重介绍JVM、GC的一些重要参数的设置来提高系统的性能。 JVM内存组成及GC相关内容请见之前的文章: JVM内存组成 GC策略&内存申请 。 JVM参数的含义 实例见 实例分析 参数名称 含义 默认值 -Xms 初始堆大小 物理内存的1/64(<1GB) 默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制. -Xmx 最大堆大小 物理内存的1/4(<1GB) 默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制 -Xmn 年轻代大小(1.4or lator) 注意 :此处的大小是(eden+ 2 survivor space).与jmap

JVM学习(4):垃圾回收

余生颓废 提交于 2020-03-13 13:18:27
进行垃圾回收的区域 :堆,方法区 运行时数据区的【堆】和【方法区】在所有线程间是共享的,进行回收 【栈】是线程私有的,所有不进行回收 什么情况下进行回收: 开发中经常有这样的写法 List<String> list = new ArrayList<>(); list.add(); list.add(); list.add(); //业务逻辑代码 return ; 这样是不合理的,list是一个局部变量,使用完毕之后应该赋值为null 这段代码,然后使用参数-XX:+PrintGCDetails -XX:+UseSerialGC public class ReferenceCountingGC { private static final int MB = 1024 * 1024; Object instance = null; private byte[] size = new byte[2 * MB]; public static void main(String[] args) { ReferenceCountingGC o1 = new ReferenceCountingGC(); ReferenceCountingGC o2 = new ReferenceCountingGC(); o1.instance = o2; o2.instance = o1; o1 = null;

In Java 8 it is shown as none of the available 4 collectors (GC) are selected by default

ε祈祈猫儿з 提交于 2020-03-13 12:32:25
问题 I have a container running a Spring Boot microservice. I am using openjdk version "1.8.0_212" under OpenJDK Runtime Environment (IcedTea 3.12.0) (Alpine 8.212.04-r0) When I use - XX:+PrintFlagsFinal flag and print the JVM parameters I expected to see -XX:+UseParallelGC as true But to my surprise none of the 4 collectors (-XX:+UseSerialGC,-XX:+UseParallelGC,-XX:+UseConcMarkSweepGC,–XX:+UseG1GC) were active. Shown below is my dockerfile: FROM openjdk:8-jdk-alpine ADD ./demo-0.0.1-SNAPSHOT.jar

Ubuntu 10.10 下安装配置 JDK 7

陌路散爱 提交于 2020-03-12 19:03:16
第一步 wget -c http://download.Oracle.com/otn-pub/java/jdk/7/jdk-7-linux-i586.tar.gz (注:如果下载不下来,建议使用迅雷下载,然后拷贝到Linux系统上。) 第二步:解压安装 sudo tar zxvf ./jdk-7-linux-i586.tar.gz -C /usr/lib/jvm cd /usr/lib/jvm sudo mv jdk1.7.0/ java-7-sun 第三步:修改环境变量 vim ~/.bashrc 添加: export JAVA_HOME=/usr/lib/jvm/java-7-sun export JRE_HOME=${JAVA_HOME}/jre export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH=${JAVA_HOME}/bin:$PATH 保存退出,输入以下命令使之立即生效。 source ~/.bashrc 第四步:配置默认JDK版本 由于Ubuntu中可能会有默认的JDK,如openjdk,所以,为了将我们安装的JDK设置为默认JDK版本,还要进行如下工作。 执行代码: sudo update-alternatives --install /usr/bin/java java /usr/lib

五大基于JVM的脚本语言

混江龙づ霸主 提交于 2020-03-12 19:01:40
最近看到有一篇文章评论了在JVM上的可以运行的排名前五脚本语言。他们分别是: Groovy。构建在强大的Java语言之上 并添加了从Python,Ruby和Smalltalk等语言中学到的诸多特征,为Java开发者提供了现代最流行的编程语言特性,而且学习成本很低(几乎为零),在开发Web,GUI,数据库或控制台程序时, 通过减少框架性代码 大大提高了开发者的效率。支持单元测试和模拟(对象),可以简化测试。无缝集成 所有已经存在的 Java对象和类库。直接编译成Java字节码,这样可以在任何使用Java的地方 使用Groovy。 JRuby。一个纯Java实现的Ruby解释器。通过JRuby,你可以在JVM上直接运行Ruby程序,调用Java的类库。很多Java编写的Ruby IDE都是使用JRuby来解释语法的。 Scala。一种多范式的编程语言,设计意图是要整合面向对象编程和函数式编程的各种特性。Scala编程语言近来抓住了很多开发者的眼球。它看起来像是一种纯粹的面向对象编程语言,而又无缝地结合了命令式和函数式的编程风格。Scala的名称表明,它还是一种高度可伸缩的语言。Scala的设计始终贯穿着一个理念:创造一种更好地支持组件的语言。 Fantom 。Fantom 前身是 (Fan) 是一个基于 Java 和 .NET 平台的编程脚本引擎,用来在运行时产生 JVM 和 .NET

JVM学习(1):类加载机制

狂风中的少年 提交于 2020-03-12 12:58:10
Class文件结构解析: 网上看到几篇文章对Java的Class文件解析写的比较全面: https://www.jianshu.com/p/247e2475fc3a http://tech.dianwoda.com/2018/03/28/jvm-classjie-xi-wen-jian-ge-shi/ https://blog.csdn.net/hywo125/article/details/90770393 类加载机制: 第一步:加载 1.获取二进制字节流 2.静态存储结构转化为方法区的运行时数据结构 运行时数据区有:【方法区,堆】,【虚拟机栈,本地方法栈,程序计数器】 3.在Java堆中生成一个类对象,作为方法区的访问入口 第二步:验证 1.验证Class文件标识:魔术Magic Number:cafebabe 2.验证Class文件版本号 3.验证常量池(常量类型,常量类型数据结构是否正确,UTF-8是否符合标准) 4.Class文件的每个部分(字段表、方法表等)是否正确 5.元数据验证(父类验证、继承验证、final字段验证等) 6.字节码验证,最复杂的步骤(指令验证) 7.符号引用验证(验证通过符号引用是否能够找到字段、方法、类) 在验证期间会报的错: IncompatibleClassChangeError--->Class文件错误 Unsupported major

对Java入口函数的认识

纵饮孤独 提交于 2020-03-11 17:00:40
Java规定了main()方法必须是公共的,以便于外部程序对主方法的访问,因为程序都是从main()方法起始的,并且main()方法也必须是静态的。 首先,为什么要用public: 因为在运行程序时,jvm要调用main方法,但我们都应该知道jvm是一个软件并不是硬件,并且它与main方法所在的包是不同的,所以jvm要调用main方法时,main方法就必须声明为public;否则jvm就无法找到和调用main方法,此时程序就无法运行。 第二,为什么要用static: 因为如果不适用static,就只能创造一个实例去调用main方法,但是jvm并不知道如何去创造一个实例,而你要创造一个实例时,必须要在main方法里头使用new这个关键字,但此时jvm无法调用main方法,所以就无法创造一个实例去调用main方法,所以main方法必须声明为static。很大程度上这是为了安全性的考虑。因为用static修饰的方法或变量是在编译时运行或分配空间的,main用static修饰后,程序就能自动找到程序的main的入口。 第三,为什么要用void: main方法根本就不需要返回值; 如果你返回了值,也不能看到,那此时jvm也不知道拿这个返回值来干什么,所以就用void。 来源: CSDN 作者: qq_39581763 链接: https://blog.csdn.net/qq_39581763