Java 让垃圾收集器更快地放弃
我正在考虑用Java编写一个程序,该程序将反复尝试一次计算,注意它会耗尽内存,更改计算,然后重试,直到成功。(内存不足是不可避免的;粗略地说,我想到的就像基因编程一样,你不能总是提前知道生成的程序是否会内存不足。)因此,看看捕捉内存不足错误的主循环 以下是简单的测试程序:Java 让垃圾收集器更快地放弃,java,memory,garbage-collection,Java,Memory,Garbage Collection,我正在考虑用Java编写一个程序,该程序将反复尝试一次计算,注意它会耗尽内存,更改计算,然后重试,直到成功。(内存不足是不可避免的;粗略地说,我想到的就像基因编程一样,你不能总是提前知道生成的程序是否会内存不足。)因此,看看捕捉内存不足错误的主循环 以下是简单的测试程序: public static void main(String[] args) { HashMap<String, Integer> hashMap = new HashMap<>();
public static void main(String[] args) {
HashMap<String, Integer> hashMap = new HashMap<>();
for (int i = 0; i < 1000000000; i++) {
hashMap.put(Integer.toBinaryString(i), i);
}
System.out.println(hashMap.size());
}
publicstaticvoidmain(字符串[]args){
HashMap HashMap=新的HashMap();
对于(int i=0;i<100000000;i++){
hashMap.put(Integer.toBinaryString(i),i);
}
System.out.println(hashMap.size());
}
内存不足并按预期以未捕获的异常退出,但这大约需要20分钟,其中大部分时间似乎是由垃圾收集器花费在英勇地寻找足够的内存以继续运行上
我如何告诉垃圾收集器我希望内存耗尽,它应该早点放弃?我不知道有什么方法可以通知垃圾收集器提前通知内存不足 但是下面的一个技巧可以立即通知您内存不足错误 为HashMap定义一个initialCapacity,运行时会出现内存不足错误
HashMap<String, Integer> hashMap = new HashMap<>(1000000000); // define initialCapacity
for (int i = 0; i < 1000000000; i++) {
hashMap.put(Integer.toBinaryString(i), i);
}
System.out.println(hashMap.size());
HashMap HashMap=newhashmap(100000000);//定义初始容量
对于(int i=0;i<100000000;i++){
hashMap.put(Integer.toBinaryString(i),i);
}
System.out.println(hashMap.size());
我不知道是否有特定的方法通知垃圾收集器提前通知内存不足
但是下面的一个技巧可以立即通知您内存不足错误
为HashMap定义一个initialCapacity,运行时会出现内存不足错误
HashMap<String, Integer> hashMap = new HashMap<>(1000000000); // define initialCapacity
for (int i = 0; i < 1000000000; i++) {
hashMap.put(Integer.toBinaryString(i), i);
}
System.out.println(hashMap.size());
HashMap HashMap=newhashmap(100000000);//定义初始容量
对于(int i=0;i<100000000;i++){
hashMap.put(Integer.toBinaryString(i),i);
}
System.out.println(hashMap.size());
您可以计算所需的内存量,并将其与Runtime.getRuntime().freemory()进行比较,以确定您的算法是否有足够的可用内存。要计算所需内存,必须考虑:
- 正如Raju所说,HashMap的容量必须传递给HashMap构造函数,以防止产生垃圾
- 示例中二进制字符串的平均大小约为29个字符或58个字节
- 每个项目的
整数的大小
- 引用任何
对象
的大小,包括字符串
和整数
例如,以下代码需要大约75 GB的内存:
HashMap<String, Integer> hashMap = new HashMap<>(1000000000);
for (int i = 0; i < 1000000000; i++) {
hashMap.put(Integer.toBinaryString(i), i);
}
System.out.println(hashMap.size());
HashMap HashMap=新的HashMap(100000000);
对于(int i=0;i<100000000;i++){
hashMap.put(Integer.toBinaryString(i),i);
}
System.out.println(hashMap.size());
此外,如果动态更改Map
的大小,但其近似容量尚未确定,则不应使用HashMap
,因为其大小调整会产生垃圾,并且在循环过程中可能会多次调整大小。相反,您应该使用另一个映射
,如树映射
,它不会生成垃圾。您可以计算所需的内存量,并将其与Runtime.getRuntime().freemory()
进行比较,以确定您的算法是否有足够的可用内存。要计算所需内存,必须考虑:
- 正如Raju所说,HashMap的容量必须传递给HashMap构造函数,以防止产生垃圾
- 示例中二进制字符串的平均大小约为29个字符或58个字节
- 每个项目的
整数的大小
- 引用任何
对象
的大小,包括字符串
和整数
例如,以下代码需要大约75 GB的内存:
HashMap<String, Integer> hashMap = new HashMap<>(1000000000);
for (int i = 0; i < 1000000000; i++) {
hashMap.put(Integer.toBinaryString(i), i);
}
System.out.println(hashMap.size());
HashMap HashMap=新的HashMap(100000000);
对于(int i=0;i<100000000;i++){
hashMap.put(Integer.toBinaryString(i),i);
}
System.out.println(hashMap.size());
此外,如果动态更改Map
的大小,但其近似容量尚未确定,则不应使用HashMap
,因为其大小调整会产生垃圾,并且在循环过程中可能会多次调整大小。相反,您应该使用另一个映射
,如树映射
,它不会生成垃圾。只是不要这样做。不要让JVM抛出OOME,甚至不要让它接近它,因为它总是浪费时间
不要等待OOME,而是定期或在循环中询问Runtime.getRuntime().freemory()
,并在太接近零之前退出(这需要一些实验)
不知道调用freemory()
的开销是多少,但是如果您在一个紧密的循环中需要它,您可以随时执行以下操作
if (i % 1000 == 0) {
... do the test
}
(或者使用i就是不要这样做。不要让JVM抛出OOME,甚至不要让它靠近它,因为它总是浪费时间
不要等待OOME,而是定期或在循环中询问Runtime.getRuntime().freemory()
,并在太接近零之前退出(这需要一些实验)
不知道调用freemory()
的开销是多少,但是如果您在一个紧密的循环中需要它,您可以随时执行以下操作
if (i % 1000 == 0) {
... do the test
}
(或者使用i为什么?当它没有内存时,你想让它耗尽内存吗?@EJP你可以这样说。就像我说的,当它