java内核机制_学习笔记-java两种核心机制-JVM和GC

我们知道C C++是依靠操作系统运行,而我们的Java不一样,是依靠jvm

而这里看到JVM又想引出什么jre(Java运行环境),jdk(Java开发工具包)

这两个经常用到的,也很简单就是使用JDK的开发工具完成JAVA的程序,交给JRE去运行。具体知道jdk>jre,我记得当初看jdk包的时候里面还含有jre,所以这也是为啥eclipse IDEA只需要导入jdk即可

而我们只运行java程序的话就按一个JRE就行了,小很多

首先让我们来看一张图了解一下什么是jvm(JAVA虚拟机)

fb1f8818009dc51a3c6bb074f94a443b.png

Java虚拟机不像vm ware一样能直接虚拟硬件模拟一台虚拟机,但是他本身作为一个虚拟机,也是有自己本身的指令集的,只要匹配的文件符合JVM对于加载文件的要求就可以

所以,我们现在的很火的kotlin(与JAVA很兼容)是不是也理所当然也可以了。可以说JVM 就是一个规范。

而怎么看这些规范和指令集呢,平常我们又不用,那我们只需要用的时候对照看看就行了

当我们随意哪一个.class文件进行javac -xxx后会生成一个白色.class  字节码文件

如图

42bd4684b98f031c95e28fb01797b7d5.png

53c8d4dc1c743418080b097b13e804da.png

07a7637bea79a6391776890cbdb24444.png

看不懂的所以需要反汇编

29b25359dbba53c41d6f394a81d47ce8.png

找到反汇编的指令即可

63ed214ed95d2a6d0c6d26e025905138.png

397a5bc1e57f16bf96a30c3d123bc161.png

d4a34b5dc3548eb1921ef6b07717a7a6.png

然后我们比如这里就有https://www.jianshu.com/p/bc91c6b46d7b找到指令集,然后对比学习,就了解的上面的coonst1等指令了,

而前面的数字是程序计数器用来标记标记执行位置这些用的

e30e68b0738b0ebdcf55e1ac0de23fd0.png

接下来我们再看底层点

e3f51ded9621549282b1eb8f553dd952.png

而我们都知道Java 堆----------------------堆存放由new创建的对象和数组-------------------------------------------------------------------------

而---------------------- 栈(线程)每一个栈都有单独的线程从栈这个大线程中分配得来(当然除了线程内存还有我们的局部变量等)

如图

9152ea125b31c7a893de9ad489140cec.png

因为不同的线程调用不同的方法都有不同的局部变量,所以都需要单独的栈内存区域。这就是栈内部的栈内存分配,而这时就引出--栈帧,在我的理解就是指针,一种数据结构,高效快捷的

找到并且运用什么插删移等

baf9ab88cb8b3285540760b3767fadd7.png

而栈我们学了数据结构都知道是先进后出!我们就可以想一想,最先调用是main方法,所以栈线程main分配了一个线程,然后main里面调用了compute这个方法,这个方法又

得分配一个线程对不,所以就又分配,但是是不是后进,所以他先出,这样也才正常,因为我们的main 从生命周期来看也确实比compute久一点

3e30c2ddc8e8a8f6891599e33b60034a.png

7f010e6687b33585aaca3df9081ef8d0.png

665a2e44e74896c669e5d3af6683a680.png

而我们知道new 的对象都是在堆中的,如果new多了对象会怎样

ad2a9a1b9750688231f526c3f52856ad.png

9f88c48165162fbc205ed33099083b45.png

249d87ba0e049eb0fa51e59eeceac8cc.png

对象多了就需要回收,怎么做到底回收哪些呢,为什么会有什么年轻代,老年代呢。往下:

GC垃圾回收

首先我们知道c c++是程序员回收,手动编写代码回收内存。      优点:随时随地高效回收,可控的,          缺点:这就很有可能遗忘或者泄露等问题造成内存一直不回收

而我们Java是自动的,开了一个系统级线程自动去检查哪些内存不用了然后回收掉。   优点:自动省心,   缺点:回收慢不及时,不是可控的

但是现在因为硬件已经发展起来的原因,回收慢这些问题已经影响不大了,所以宁愿回收慢也不愿意一直占用忘记回收。

再看一个图:

如下(( 这个图也说明了static为什么能全部引用,它在GC Root里))

9b3e160fde62002e315cbc138f053d39.png

看完这个图,我们可以这样理解,我们jvm引擎一个线程或者其他在找GC Root相关联的,没有gcroot有关的就回收

比如我们xxx.class对象,就是一种GCRoot,那么与xxx.class相关的什么方法啊变量啊也都能存活。反之就回收

ef835f244f47e76e9e2d76a6bea9d6f9.png

并且经过一次GC检测,分代年龄就会+1。而满了后又会右移,当对象分代年龄+到15,就会到lao老年代

如果弄一个死循环也一直new对象,也在main里面又无法脱离GCRoot会怎样,就是不会回收对吧,就会一直不被检测回收但又

一直new就会不停产生到堆里面然后检测+1然后右移然后进入老年代如图,而且还是一个动态的过程

27ea09cb3e8cd36cf9855abb651a7575.png

很多时候JAVA虚拟机因为full gc ,minor gc等产生STW(就是停止一切线程然后清理一下)这时客户感觉就是卡死了几秒然后就恢复了,因为STW也不是很特别慢,应该说是full gc慢一点minor gc是比较快的。

这时候就引出调优------------就是减少STW产生次数

第一就是full gc减少STW

比如这个案例,产生60m大小的内存即New对象,可以是一个动作new 下单啊或者其他什么之类,抢东西new buy啊,注册啊,反正new的空间,

很快eden800m是不是就满了大概13秒13X60=780,这时候会回收minor gc对吧,但是回收的此时此刻还有对象进来怎么办,不能放eden了,这时根据规则就放S0这些

但是我们发现这里面因为s0太小,(超过一半内存的大对象理论)所以就会直接放进老年代。不停不停的到老年代不就产生最不喜欢的full gc(STW)

d79f3b1b43e3cd1f8744047df7a37a5c.png

所以

我们需要怎样调优:把老年代调小

410f62da570bfaa94fbfa19ee58130c3.png

这样之后我们发现好处一:minor的次数变少了,时间也变久了,因为根据原理比如下单,下一秒这个下单对象是不是就可能是一个变垃圾了直接就干掉了都不用检测加入S0 s1老年代等

好处二就是:会发现这是一个eden和s0 s1的循环,根本不会进入老年代

调优完毕

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这是一个 Java 运行时的命令行选项,表示将文件编码设置为 UTF-8。它可以在运行 Java 程序时作为参数传入,例如:"java -Dfile.encoding=utf-8 MyProgram"。 ### 回答2: "picked up java_tool_options: -dfile.encoding=utf-8" 这个提示信息通常出现在使用Java编译和执行程序的时候。这个提示就像一个告警,它意味着Java虚拟机在启动时发现了某个程序中设置了这个环境变量,这个环境变量指定了Java编译和执行程序时需要采用的字符集编码格式。 Java编译和执行时字符集编码是非常重要的,因为它直接影响着程序的运行效果和程序的输出。如此设置 -dfile.encoding=utf-8 ,是要指定编译和执行时使用的字符集编码格式为utf-8,这意味着这个程序是一个多语言的应用程序,他的输出包含多种语言的字符和符号。 这个警告信息不是一个错误信息,只是一个提示性的信息。虽然看上去有点烦人,但它并不会影响程序的运行效果。 而且,如果你不想看到这个提示信息,可以在启动命令加上 -Djava_tool_options="-Dfile.encoding=UTF-8",这样就可以屏蔽这个提示信息。 总之,"picked up java_tool_options: -dfile.encoding=utf-8" 这个提示信息提醒着我们在编写Java程序的时候一定要注意字符集编码格式的设置,以确保程序不会因字符集编码问题而出错。 ### 回答3: "picked up java_tool_options: -dfile.encoding=utf-8" 是一条提示信息,出现在使用 Java 命令行工具运行程序时的标准输出中。它告诉我们 Java 虚拟机(JVM)正在读取并使用环境变量中的 java_tool_options 参数。其中,-dfile.encoding=utf-8 部分是一个 JVM 系统属性,用于指定文件编码格式,这里指定为 UTF-8。 Java 的文件编码格式对于文本处理、字符集转换等操作非常重要。如果没有正确指定编码,可能会导致程序输出中文乱码、读取的文本文件内容出现错乱等问题。因此,当使用 Java 程序处理文本时,建议始终使用正确的编码方式进行操作,并在必要时使用 -dfile.encoding 参数进行指定。 值得注意的是,java_tool_options 环境变量是一个用于设置 JVM 系统属性的标准变量,可以用于调整 JVM 的运行参数,例如指定堆大小、开启调试模式等。具体使用方法可以参考相关文档或工具书。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值