不安全的代码: 教你“随心所欲”地在内存中操作Java的类和对象(2)

本文探讨了Java中对象表示方法——OOPs与CompressedOOPs的区别与联系,介绍了CompressedOOPs如何通过32位对象偏移表示64位的字节偏移,从而在64位系统中有效利用内存,节省空间。

写在前面的话:译者本身能力有限,不能逐字逐句地翻译。本人翻译的目标是为了能给大家说得简单明了,所以会采取意译的方法。如果有措辞不正确或不好的地方,讲大家不吝赐教,谢谢!

原文地址:https://zeroturnaround.com/rebellabs/dangerous-code-how-to-be-unsafe-with-java-classes-objects-in-memory/2/

OOPs 与 Compressed OOPs

每一个Java对象在堆中被表示为一个普通对象指针(Ordinary Object Pointer,OOP)。每个OOP是一个指向Java堆内空间的一个受管理(控制)的指针。指向的空间是Java进程内的虚拟地址表示的一块连续的空间。

一般情况下,OOP的大小与宿主机的指针一样,也就是说在LP64数据模型系统中,OOP的大小是64位的。在一个ILP32数据模型系统中,堆的最大空间要小于4G。这有点小,对于很多应用来说不够用。

OOP指针指向的Java对象在堆中是以8字节地址边界对齐的。Compressed OOPs(压缩过的指针——好土的名字吧,请原谅笔者的翻译,水平有限呀)在Java虚拟机的堆中,很多时候(而不是所有情况都是),用32位的对象位移(object offset)来表示64位的字节位移(byte offset)[笔者认为,这句话可以认为:用32位的对象指针来替代64位对象指针]。因为Compressed OOP中的offset(笔者认为翻译成“位移”反而更让人搞不懂)是object offset,而不是byte offset。32位的object offset可以寻址的范围是4,000,000,000*objects*,也就是32GB的堆内空间。[在这里作者说得很让人发晕,不过笔者认为他就说了一件事儿:以前普通对象指针是按字节计算对象在内存中位置的,而现在Compressed OOPs则是按8字节为单位计算的。这也是为什么32位字节的指针本来只能寻址4GB的空间,现在就达到32GB了。实现这个技术的基础就在于段落第一句,因为Java对象在64位机器中是以8字节地址边界对齐的。] 为了能够正确找到对象的位置,Compressed OOPs的值需要乘以8再加上Java堆的基址才可以。使用compressed OOPs技术的对象的大小和在ILP32模式下的对象大小一般大。

Compressed OOP在Java v6u23及以后的版本中默认是打开的。在Java7中,在64位JVM中若启动java进程时”-Xmx”没有指定值或者其值小于32GB时,Compressed OOP技术是默认打开的。JDK6中6u23之前的版本需要在启动Java进程中添加“-XX:+UserCompressedOops”选项才能够使用这个特性。具体见这个链接:(http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html


先简单地说下SampleClass

在这篇文章中,我们将用一个样本类——SampleClass,正如其名一样是个样例——为例来探索下其对象访问、其属性地layout(部局)等等。这个类很简单,其包含3个基本类型变量,并且继承SampleBaseClass类以说明继承反映在内存layout上是什么样子的。类的定义如下(这些类的代码也可以在github上找到):

public final class SampleClass extends SampleBaseClass {

    private final static byte b = 100;

    private int i = 5;
    private long l = 10;

    public SampleClass() {

    }

    public SampleClass(int i, long l) {
        this.i = i;
        this.l = l;
    }

    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
    }

    public long getL() {
        return l;
    }

    public void setL(long l) {
        this.l = l;
    }

    public static byte getB() {
        return b;
    }
}
public class SampleBaseClass {

    protected short s = 20;
}

To Be Continued…

2章 使用的基本技术及工具 2.1 开发环境 开发平台:Windows10; 数据库:MySQL; JDK:1.7 及以上; 编程语言:Java; 开发根工具:Android Studio 2022 运行设备:android 手机或虚拟机。 2.2 使用的技术及工具介绍 2.2.1 Spring 框架 Android是谷歌旗下著名的移动开源操作系统。这个系统的内核是Linux。 该系统具有很高的兼容性,可以用在包括智能手机、电视、平板等诸多设备上。有着高度兼容的特性。最重要的是,Android开源的属性使开发者可以自由的通过Android系统进行开发。而本系统就是基于Android开发的一款医院挂号系统。Android的开源属性在07年已经推出,就受到了开发者的高度赞扬,而Android开发也成为一时间最热门的词语。开发者可以在Android系统上尽情挥舞画笔随心所欲地创作。Android作为以智能手机、平板、电视为主战场的可移动设备操作系统,使用度适用性非常广泛,远远超过诸如塞班、IOS等系统。在Android平台上,APP的体系结构很大幅度的上简化了组件的工作。在这之中,Java成为了APP开发的唯一语言,Java通过跨平台功能,无需编译基于Android框架开发的软件应用程序,即任意一台搭载了Android的设备均可运行。 2.2.2 SQLite介绍 SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它的设计目标是嵌入式的,而且已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如PHP、Java等,还有ODBC接口,同样比起MySQL、PostgreSQL这两款开源的世界著名数据库管理系统来讲,它的处理速度比他们都快。SQLite第一个Alpha版本诞生于2000年5月。 至2021年已经接近有21个年头,SQLite也迎来了一个版本 SQLite 3已经发布。 2.2.3 B/S架构介绍 B/S结构是目前使用最多的结构模式,它可以使得系统的开发更加的简单,好操作,而且还可以对其进行维护。使用该结构时只需要在计算机中安装数据库,一些很常用的浏览器就可以了。浏览器就会与数据库进行信息的连接,可以实现很多的功能,B/S结构是可以直接进行使用的,而且B/S结构在使用中极大的减少了工作的维护。基于B/S的软件,所有的数据库之间都是相互独立的,因此是非常安全的。因为基于B/S结构可以清楚的看到系统正在处理的业务,并且能够及时的让管理人员做出决策,这样就可以避免企业的损失。B/S结构的基本特点是集中式的管理模式,用户使用系统生成数据后,这些数据就可以存储到系统的数据库中,方便日后能够用到,这样就可以满足人们的所有的需求。 2.2.4 Java语言介绍 Java是由SUN公司推出,该公司于2010年被oracle公司收购。Java本是印度尼西亚的一个叫做爪洼岛的英文名称,也因此得来java是一杯正冒着热气咖啡的标识。Java语言在移动互联网的大背景下具备了显著的优势广阔的前景,它是面向对象的,分布式的,动态的,具有平台无关性、安全性、健壮性。Java语言的基本语句语法C++一样,但是它面向对象的技术更加彻底,因为Java要求将所有的内容都必须封装成,把作为程序的基本单位。由于允许外有变量、方法。 Java语言的分布式体现在数据分布操作分布,它是面向网络的语言,可以处理TCP/IP协议,它也支持客户机/服务器的计算模式。Java语言的动态性是指在运行时是动态安装的,使得Java可以动态的维护程序。Java支持指针,对内存访问的所有操作都是通过对象实例化实现的,这样就避免了指针操作中易产生的错误,同时也预防了病毒对系统的破坏威胁。 Java语言的编程风格与C语言非常接近,它继承了C++面向对象技术的核心,它面世之后发展迅速,非常流行,对高级C语言形成了很大的冲击。业内人士称之为“一次编译、到处执行”。当然java也有缺点,在每次执行编译后,字节码都需要消耗一定的时间,在某些程度上降低了性能。但是这并影响java成为此次设计语言的选择。Java语言简单易学,使用它的编程时间短,功能性强,开发者学习起来更简便、更快。Java的主要特性有以下几个: (1)面向对象 面向对象有四个特点:封装、继承、多态、抽象。抽象是指忽略一个问题中的次要部分,关注主要部分。多态是指对同一种消息做出的同反应。继承是指在原有的父方法基础上增加自己独有的方法,而改变原来父。 (2)平台无关性 Java编译出来的是字节码,直接由虚拟机执行。在任何平台上,只要有Java虚拟机,Java代码都能运行。 (3)可靠性安全Java内存的访问都必须通过对象的实例变量来实现,避免了指针中出现的错误。 (4)多线程 Java提供了多线程功能,利用编程实现同一时间同时工作的功能。 以这样的形式写出一段基于ssm的图书管理系统文档
最新发布
06-17
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值