栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

根据JVM的内存粒度确定阵列的最佳大小

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

根据JVM的内存粒度确定阵列的最佳大小

有趣的主意。我认为确定此问题的更便捷的方法是实际衡量使用情况。示例程序:

public class FindMemoryUsage {    public static void main(String[] args) {        for (int i=0; i<50; i+=2) { long actual = getActualUsageForN(i); System.out.println(i + " = " + actual); long theoretical = getTheoreticalUsageForN(i); if (theoretical != actual) {     throw new RuntimeException("Uh oh! Mismatch!"); }        }    }    private static long getTheoreticalUsageForN(long count) {        long optimal = (Unsafe.ARRAY_BYTE_base_OFFSET + Unsafe.ARRAY_BYTE_INDEX_SCALE * count);        return ((optimal - 1) & ~7) + 8;    }    private static long getActualUsageForN(int count) {        System.gc();        byte[][] arrays = new byte[3000000][];        long begin = usedMemory();        for (int i=0; i<arrays.length; i++) { arrays[i] = new byte[count];        }        long end = usedMemory();        return Math.round((end - begin) / (double) arrays.length);    }    private static long usedMemory() {        return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();    }}

该程序为您提供此信息:

0 = 162 = 164 = 166 = 248 = 2410 = 2412 = 2414 = 3216 = 3218 = 3220 = 3222 = 4024 = 4026 = 4028 = 4030 = 4832 = 4834 = 4836 = 4838 = 5640 = 5642 = 5644 = 5646 = 6448 = 64

该数据来自使用率的实际计算和基于

sun.misc.Unsafe
的常数和8字节舍入的理论使用率。这意味着您可以像建议的那样使用这些常量来“四舍五入”:

private static int roundSizeUp(int from) {    long size = (Unsafe.ARRAY_BYTE_base_OFFSET + Unsafe.ARRAY_BYTE_INDEX_SCALE * from);    long actual = ((size - 1) & ~7) + 8;    return (int) (actual - Unsafe.ARRAY_BYTE_base_OFFSET) / Unsafe.ARRAY_BYTE_INDEX_SCALE;}

这是特定于VM的代码,但是

getActualUsageForN
如果需要更多的可移植性,您可能可以根据该策略找到如何执行此操作。

请注意,这不是生产质量的代码:您需要仔细考虑溢出,并将

Unsafe
引用更改为实际上适用于所使用数组类型的常量。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/509329.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号