? ? ? ? ?自从c与c++换成用java开发后发现写代码的速度大大提升而难度也大大的降低了,但发现对内存的管理开始模糊了,心里总有疑问写的东西运行时会占用了多少内存空间?内存占用空间可以说一直是对开发者非常重要,很多时候就觉得它就是战场,无论是什么开发语言都应该要撑控,而java开发由于是jvm管理内存,所以jvm调优应该每一个java程序员应该熟练的知识。
在Java中,查看一个变量、方法或类(对象)占用的内存空间并不直观,因为Java虚拟机(JVM)对内存分配是基于对象实例进行的。变量本身不直接占用内存,而是它们所引用的对象占用内存。以下是一些分析和估算的方法:
单个变量:
方法:
类或对象占用的空间:
java.lang.instrument.Instrumentation
接口可以在运行时获取对象大小,但需要通过特殊的手段注入到应用中,例如前面提到的代理类方式。使用java.lang.instrument.Instrumentation
接口获取Java对象的内存大小,首先需要创建一个代理类,并在JVM启动时通过 -javaagent
参数注入?,代码如下:
import java.lang.instrument.Instrumentation;
/**
* 获取内存大小
*/
public class MemoryAgent {
private static volatile Instrumentation instrumentation;
public static void premain(String agentArgs, Instrumentation inst) {
instrumentation = inst;
}
public static long getObjectSize(Object obj) {
if (instrumentation != null) {
return instrumentation.getObjectSize(obj);
} else {
throw new IllegalStateException("未初始化!");
}
}
}
?编译该代理类并打包成jar文件(例如:memory-agent.jar)。
?在运行Java应用程序时,通过 -javaagent
参数指定代理类和jar包的位置:
java -javaagent:path/to/memory-agent.jar -jar your-application.jar
?在应用中,就可以调用MemoryAgent.getObjectSize()
来获取对象的内存占用大小了
public class Main {
public static void main(String[] args) {
String testStr = "Hello, World!";
// 获取字符串对象的内存占用大小
long size = MemoryAgent.getObjectSize(testStr);
System.out.println("The size of the string object is: " + size + " bytes");
}
}
说明:getObjectSize()
返回的是特定平台上的对象大小,包括对象头、实例数据以及对齐填充等部分,但不包括任何对象引用的对象本身所占用的内存。如果对象间存在复杂的引用关系,可能需要更复杂的分析工具来了解整个内存占用情况。?
JVM调优基础是指对Java虚拟机(JVM)进行性能优化的基本原理和步骤,它涉及到多个方面,包括但不限于内存管理、垃圾回收策略、线程管理和编译器优化等。以下是JVM调优的一些基本知识点:
内存管理与GC调优:
JVM参数设置:
-Xms
?和?-Xmx
:设定初始和最大堆大小。-XX:NewRatio
:控制新生代与老年代的比例。-XX:SurvivorRatio
:新生代中eden与survivor空间的比例。-XX:+UseConcMarkSweepGC
?或?-XX:+UseG1GC
?等:指定垃圾收集器。-XX:MaxTenuringThreshold
:对象在新生代中经历多少次Minor GC后晋升至老年代的阈值。监控与诊断工具:
代码优化:
线程与并发优化:
JIT即时编译优化:
常见的调优指标是降低全gc的次数,?涉及最常用的调优参数是-Xms
?和?-Xmx。
总的来说,JVM调优是一个综合性的过程,需要结合具体应用场景、业务需求以及硬件资源状况,通过分析监控数据、合理配置JVM参数以及优化代码实现性能提升。调优过程中要注意权衡不同的性能指标,如响应时间、吞吐量和内存使用效率等。