使用整数标记和按位操作是减少大容量对象的内存占用的有效方法吗?

>记忆足迹

我的理解是,在JVM实现中通常将一个布尔值存储为一个int.它是否正确?在这种情况下,32个标志代表了大量的内存占用量减少.

虽然JVM实现当然不尽相同,但并不总是如此.
>表演

我的理解是,cpu是非常数字驱动的,按位操作与计算中的功能一样高效.

对布尔运算使用按位运算,是否有性能损失 – 甚至增益?
>替代品

有没有更好的方式来完成同样的事情?枚举允许标志的组合,即FLAGX = FLAG1 | FLAG2?

示例代码

注意最后一个方法propogateMove()是递归的,每秒可以调用几百次,并且对应用程序的响应性有直接影响,因此使用标志来避免逻辑位和调用其他方法.

// FLAGS helper functions
private final void setclear(int mask,boolean set) { if (set) set(mask); else clear(mask); }
private final void set(int mask) { flags |= mask; }
private final void clear(int mask) { flags &= ~mask; }
private final boolean test(int mask) { return ((flags & mask) == mask); }



// Flags //////////////////////////////////////////////////////////////////////

private static final boolean HORIZONTAL          = true;
private static final boolean VERTICAL            = false;

private static final int ORIENT                  = 0x00000001;
private static final int disPLAY                 = 0x00000002;
private static final int HSHRINK                 = 0x00000004;
private static final int VSHRINK                 = 0x00000008;
private static final int SHRINK = HSHRINK | VSHRINK;

private static final int TILE_IMAGE              = 0x00000010;
private static final int CURSOR                  = 0x00000020;
private static final int MOUSEINSIDE             = 0x00000040;
private static final int MOUSEINSIDE_BLOCKED     = 0x00000080;

private static final int CONSTRAIN               = 0x00000100;
private static final int CONSTRAIN_DESCENDENT    = 0x00000200;
private static final int PLACE                   = 0x00000400;
private static final int PLACE_DESCENDENT        = 0x00000800;
private static final int REFLOW = CONSTRAIN | CONSTRAIN_DESCENDENT | PLACE | PLACE_DESCENDENT;

private static final int PACK                    = 0x00001000;
private static final int CLIP                    = 0x00002000;
private static final int HAS_WIDTH_SLACK         = 0x00004000;
private static final int HAS_HEIGHT_SLACK        = 0x00008000;

private static final int ALIGN_TOP               = 0x00010000;
private static final int ALIGN_BottOM            = 0x00020000;
private static final int ALIGN_LEFT              = 0x00040000;
private static final int ALIGN_RIGHT             = 0x00080000;
private static final int ALIGNS = ALIGN_TOP | ALIGN_BottOM | ALIGN_LEFT | ALIGN_RIGHT;
private static final int ALIGN_TOPLEFT = ALIGN_TOP | ALIGN_LEFT;
private static final int ALIGN_TOPRIGHT = ALIGN_TOP | ALIGN_RIGHT;
private static final int ALIGN_BottOMLEFT = ALIGN_BottOM | ALIGN_LEFT;
private static final int ALIGN_BottomrIGHT = ALIGN_BottOM | ALIGN_RIGHT;

private static final int ENTER_TRAP              = 0x00100000;
private static final int LEAVE_TRAP              = 0x00200000;
private static final int _MOVE_TRAP              = 0x00400000;
private static final int MOVE_TRAP               = 0x00800000;

private static final int CHILDREN_READ_TRAP      = 0x01000000;
private static final int CHILDREN_TRAP           = 0x02000000;
private static final int PLACE_CLEAN             = 0x03000000;

private static final int SHRINK_TRAP             = 0x04000000;
private static final int HSHRINK_TRAP            = 0x10000000;
private static final int VSHRINK_TRAP            = 0x20000000;

//private static final int UNUSED                = 0x40000000;
//private static final int UNUSED                = 0x80000000;




// Flags in switch ////////////////////////////////////////////////////////////

/** get align value as a string from align flags */
private JS alignToJS() {
    switch(flags & ALIGNS) {
        case (ALIGN_TOPLEFT):
            return SC_align_topleft;
        case (ALIGN_BottOMLEFT):
            return SC_align_bottomleft;
        case (ALIGN_TOPRIGHT):
            return SC_align_topright;
        case (ALIGN_BottomrIGHT):
            return SC_align_bottomright;
        case ALIGN_TOP:
            return SC_align_top;
        case ALIGN_BottOM:
            return SC_align_bottom;
        case ALIGN_LEFT:
            return SC_align_left;
        case ALIGN_RIGHT:
            return SC_align_right;
        case 0: // CENTER
            return SC_align_center;
        default:
            throw new Error("This should never happen; invalid alignment flags: " + (flags & ALIGNS));
    }
}




// Flags in logic /////////////////////////////////////////////////////////////

private final boolean propagateMove(int mousex,int mousey) throws JSExn {
    // start with pre-event _Move which preceeds Enter/Leave
    if (test(_MOVE_TRAP)) {
        if (Interpreter.CASCADE_PREVENTED == justTriggerTraps(SC__Move,JSU.T)) {
            // _Move cascade prevention induces Leave
            propagateLeave();
            // propagate cascade prevention
            return true;
        }
    }

    // REMARK: anything from here on in is a partial interruption relative
    // to this Box so we can not call propagateLeave() directly upon it
    int i;
    boolean interrupted = false;

    if (!test(PACK)) {
        // absolute layout - allows for interruption by overlaying siblings
        for (Box b = getChild(i=treeSize()-1); b != null; b = getChild(--i)) {
            if (!b.test(disPLAY)) {
                continue;
            }
            if (interrupted) {
                b.propagateLeave();
                continue;
            }
            int b_mx = mousex-getXInParent(b);
            int b_my = mousey-getYInParent(b);
            if (b.inside(b_mx,b_my)) {
                if (b.propagateMove(b_mx,b_my)) {
                    interrupted = true;
                }
            } else {
                b.propagateLeave();
            }
        }
    } else {
        // packed layout - interrupted still applies,plus packedhit shortcut
        boolean packedhit = false;
        for (Box b = getChild(i=treeSize()-1); b != null; b = getChild(--i)) {
            if (!b.test(disPLAY)) {
                continue;
            }
            if (packedhit) {
                b.propagateLeave();
                continue;
            }
            int b_mx = mousex-getXInParent(b);
            int b_my = mousey-getYInParent(b);
            if (b.inside(b_mx,b_my)) {
                packedhit = true;
                if (b.propagateMove(b_mx,b_my)) {
                    interrupted = true;
                }
            } else {
                b.propagateLeave();
            }
        }
    }

    // child prevented cascade during _Move/Move which blocks
    // Enter on this Box - invoking Leave if necessary
    if (interrupted) {
        if (test(MOUSEINSIDE)) {
            if (!test(MOUSEINSIDE_BLOCKED)) {
                // mouse prevIoUsly inside,Now blocked so invoke Leave
                set(MOUSEINSIDE_BLOCKED);
                if (test(LEAVE_TRAP)) {
                    justTriggerTraps(SC_Leave,JSU.T);
                }
            }
        } else {
            // mouse not prevIoUsly inside,Enter not yet triggered,so
            // do not invoke Leave
            set(MOUSEINSIDE);
            set(MOUSEINSIDE_BLOCKED);
        }
        // propagate cascade prevention 
        return true;
    }

    // set cursor if applicable to this Box
    if (test(CURSOR)) {
        Surface s = getSurface();
        if (s!=null && !s.cursorset) {
            s.cursor = JSU.toString(getAndTriggerTraps(SC_cursor));
            s.cursorset = true;
        }
    }

    // fire Enter traps
    if (!test(MOUSEINSIDE)) {
        set(MOUSEINSIDE);
        if (test(ENTER_TRAP)) {
            justTriggerTraps(SC_Enter,JSU.T);
        }
    }

    // finish post-event Move which follows Enter/Leave
    if (test(MOVE_TRAP)) {
        if (Interpreter.CASCADE_PREVENTED == justTriggerTraps(SC_Move,JSU.T)) {
            // propagate cascade prevention
            return true;
        }
    }

    // propagation uninterrupted
    return false;
}

解决方法

It is my understanding that commonly a boolean is stored as an int in a JVM implementation. Is this correct?

当然这取决于JVM的实现,但对主流cpu的实现可能是正确的.

In which case surely the 32 flags represent a large memory footprint reduction.

如果你在一个类中实际上有32个标志,那么该类的大量实例就是.如果你没有超过几百个例子,那就不用担心了.

It is my understanding that cpus are very number driven and bitwise operations are about as efficient as things come in computing.

这是真的.

Is there a performance penalty – or even gain – to using bitwise operations over boolean operations?

这也取决于内存使用情况.如果你只用几个对象非常集中,那么按位操作可能会减慢速度.如果你有很多对象,由于更好的缓存行为,减少的内存可能会提高性能.

Is there a better way of accomplishing the same thing? Does an Enum allow the combination of flags i.e. FLAGX = FLAG1 | FLAG2?

而不是自己做点阵操作,你可以(而且应该)使用一个BitSet.是的,如果你可以使用Enums和一个EnumSet,它会更清晰,但是如果你有许多枚举,由于多个EnumSet实例的开销,它可能不会产生所需的内存节省.

Java整数标记和用于内存缩减的按位操作的更多相关文章

  1. Cocoapods1.3.2 Xcode8 pod安装生成Pods项目Abort trap:6

    192:podssetcxm$podinstall–verbose准备分析依赖关系检查目标是否整合使用ARCHS设置构建目标Pods-podss的体系结构:(“)解决Podfile的依赖关系将已解析的规范与沙箱清单进行比较一个FMDB下载依赖项–>安装FMDB(2.6.2)copyingFMDBfrom/Users/etcxm/Library/Caches/CocoaPods/Pods/Relea

  2. GNU Makefile等效于shell的“TRAP”命令,用于在退出时简要识别构建失败

    取消编辑–我的解决方案实际上并没有像我曾经希望的那样工作.STYMIED!

  3. Java整数标记和用于内存缩减的按位操作

    使用整数标记和按位操作是减少大容量对象的内存占用的有效方法吗?在这种情况下,32个标志代表了大量的内存占用量减少.虽然JVM实现当然不尽相同,但并不总是如此.>表演我的理解是,cpu是非常数字驱动的,按位操作与计算中的功能一样高效.对布尔运算使用按位运算,是否有性能损失–甚至增益?

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部